[gcc r15-8526] gccrs: Refactor HIR to reduce the amount of raw pointers

Arthur Cohen cohenarthur@gcc.gnu.org
Fri Mar 21 11:36:52 GMT 2025


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

commit r15-8526-gc29a3bc945c2d018f75974c12c29aaf99a978984
Author: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Date:   Tue Feb 27 13:43:37 2024 +0100

    gccrs: Refactor HIR to reduce the amount of raw pointers
    
    Attempt to use references and smart pointers whenever possible.
    
    gcc/rust/ChangeLog:
    
            * backend/rust-compile-base.cc (HIRCompileBase::compile_function_body):
            Remove usage of get function to retrieve a raw pointer.
            * backend/rust-compile-base.h:
            Change API usage from raw pointer to a reference.
            * backend/rust-compile-block.cc (CompileBlock::compile): Likewise.
            (CompileBlock::visit): Likewise.
            (CompileConditionalBlocks::visit): Likewise.
            * backend/rust-compile-block.h: Likewise.
            * backend/rust-compile-expr.cc (CompileExpr::Compile): Likewise.
            (CompileExpr::visit): Likewise.
            (check_match_scrutinee): Likewise.
            (CompileExpr::array_value_expr): Likewise.
            (CompileExpr::array_copied_expr): Likewise.
            (CompileExpr::generate_closure_function): Likewise.
            (CompileExpr::generate_possible_fn_trait_call): Likewise.
            * backend/rust-compile-expr.h: Likewise.
            * backend/rust-compile-fnparam.cc (CompileFnParam::compile): Likewise.
            (CompileFnParam::visit): Likewise.
            * backend/rust-compile-fnparam.h: Likewise.
            * backend/rust-compile-implitem.cc (CompileTraitItem::visit): Likewise.
            * backend/rust-compile-intrinsic.cc (compile_fn_params): Likewise.
            * backend/rust-compile-item.cc (CompileItem::visit): Likewise.
            * backend/rust-compile-pattern.cc (CompilePatternCheckExpr::visit):
            Likewise.
            (compile_range_pattern_bound): Likewise.
            (CompilePatternBindings::visit): Likewise.
            (CompilePatternLet::visit): Likewise.
            * backend/rust-compile-pattern.h: Likewise.
            * backend/rust-compile-resolve-path.cc (ResolvePathRef::resolve):
            Likewise.
            (HIRCompileBase::query_compile): Likewise.
            * backend/rust-compile-stmt.cc (CompileStmt::visit): Likewise.
            * backend/rust-compile-struct-field-expr.cc (CompileStructExprField::Compile):
            Likewise.
            (CompileStructExprField::visit): Likewise.
            * backend/rust-compile-struct-field-expr.h: Likewise.
            * backend/rust-compile-type.cc (TyTyResolveCompile::visit): Likewise.
            * backend/rust-compile-var-decl.h: Likewise.
            * backend/rust-compile.cc: Likewise.
            * backend/rust-mangle-v0.cc (v0_inherent_or_trait_impl_path): Likewise.
            * checks/errors/borrowck/rust-bir-builder-expr-stmt.cc (ExprStmtBuilder::visit):
            Likewise.
            * checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h: Likewise.
            * checks/errors/borrowck/rust-bir-builder-pattern.h: Likewise.
            * checks/errors/borrowck/rust-bir-builder-struct.h: Likewise.
            * checks/errors/borrowck/rust-bir-builder.h: Likewise.
            * checks/errors/borrowck/rust-function-collector.h: Likewise.
            * checks/errors/privacy/rust-privacy-reporter.cc (PrivacyReporter::check_type_privacy):
            Likewise.
            (PrivacyReporter::visit): Likewise.
            * checks/errors/privacy/rust-privacy-reporter.h: Likewise.
            * checks/errors/privacy/rust-reachability.cc (ReachabilityVisitor::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::visit): Likewise.
            * checks/lints/rust-lint-marklive.h: Likewise.
            * hir/rust-hir-dump.cc (Dump::visit): Likewise.
            * hir/tree/rust-hir-expr.h: Likewise.
            * hir/tree/rust-hir-item.h: Likewise.
            * hir/tree/rust-hir-path.h: Likewise.
            * hir/tree/rust-hir-pattern.h: Likewise.
            * hir/tree/rust-hir-stmt.h: Likewise.
            * hir/tree/rust-hir-type.h: Likewise.
            * hir/tree/rust-hir.h: Likewise.
            * typecheck/rust-autoderef.cc: Likewise.
            * typecheck/rust-hir-dot-operator.cc (MethodResolver::select):
            Likewise.
            * typecheck/rust-hir-inherent-impl-overlap.h: Likewise.
            * typecheck/rust-hir-path-probe.cc (PathProbeType::process_impl_item_candidate):
            Likewise.
            (PathProbeImplTrait::process_trait_impl_items_for_candidates): Likewise.
            * typecheck/rust-hir-trait-resolve.cc (TraitResolver::resolve_trait):
            Likewise.
            (TraitItemReference::resolve_item): Likewise.
            * typecheck/rust-hir-type-check-base.cc: Likewise.
            * typecheck/rust-hir-type-check-base.h: Likewise.
            * typecheck/rust-hir-type-check-enumitem.cc (TypeCheckEnumItem::Resolve):
            Likewise.
            (TypeCheckEnumItem::visit): Likewise.
            * typecheck/rust-hir-type-check-enumitem.h: Likewise.
            * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::Resolve):
            Likewise.
            (TypeCheckExpr::visit): Likewise.
            (TypeCheckExpr::resolve_fn_trait_call): Likewise.
            * typecheck/rust-hir-type-check-expr.h: Likewise.
            * typecheck/rust-hir-type-check-implitem.cc (TypeCheckTopLevelExternItem::Resolve):
            Likewise.
            (TypeCheckTopLevelExternItem::visit): Likewise.
            (TypeCheckImplItem::visit): Likewise.
            (TypeCheckImplItemWithTrait::visit): Likewise.
            * typecheck/rust-hir-type-check-implitem.h: Likewise.
            * typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit): Likewise.
            (TypeCheckItem::resolve_impl_item): Likewise.
            (TypeCheckItem::resolve_impl_block_substitutions): Likewise.
            (TypeCheckItem::resolve_impl_block_self): Likewise.
            * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::visit): Likewise.
            (TypeCheckExpr::resolve_segments): Likewise.
            * typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::Resolve):
            Likewise.
            (TypeCheckPattern::visit): Likewise.
            (ClosureParamInfer::Resolve): Likewise.
            (ClosureParamInfer::visit): Likewise.
            * typecheck/rust-hir-type-check-pattern.h: Likewise.
            * typecheck/rust-hir-type-check-stmt.cc (TypeCheckStmt::Resolve):
            Likewise.
            (TypeCheckStmt::visit): Likewise.
            * typecheck/rust-hir-type-check-stmt.h: Likewise.
            * typecheck/rust-hir-type-check-struct-field.h: Likewise.
            * typecheck/rust-hir-type-check-struct.cc (TypeCheckStructExpr::TypeCheckStructExpr):
            Likewise.
            (TypeCheckStructExpr::Resolve): Likewise.
            (TypeCheckStructExpr::resolve): Likewise.
            (TypeCheckStructExpr::visit): Likewise.
            * typecheck/rust-hir-type-check-type.cc (TypeCheckResolveGenericArguments::resolve):
            Likewise.
            (TypeCheckType::Resolve): Likewise.
            (TypeCheckType::visit): Likewise.
            (TypeCheckType::resolve_root_path): Likewise.
            (TypeResolveGenericParam::Resolve): Likewise.
            (TypeResolveGenericParam::visit): Likewise.
            (ResolveWhereClauseItem::visit): Likewise.
            * typecheck/rust-hir-type-check-type.h: Likewise.
            * typecheck/rust-hir-type-check.cc (TraitItemReference::get_type_from_fn):
            Likewise.
            * typecheck/rust-hir-type-check.h: Likewise.
            * typecheck/rust-type-util.cc (query_type): Likewise.
            * typecheck/rust-typecheck-context.cc (TypeCheckContextItem::TypeCheckContextItem):
            Likewise.
            * typecheck/rust-tyty-bounds.cc (TypeBoundsProbe::scan): Likewise.
            (TypeCheckBase::get_predicate_from_bound): Likewise.
            * typecheck/rust-tyty-call.cc (TypeCheckCallExpr::visit): Likewise.
            (TypeCheckMethodCallExpr::go): Likewise.
            (TypeCheckMethodCallExpr::check): Likewise.
            * typecheck/rust-tyty-subst.cc: Likewise.
            * typecheck/rust-tyty.cc (BaseType::monomorphized_clone): Likewise.
            (VariantDef::VariantDef): Remove copy constructor.
            (VariantDef::operator=): Change to move operator.
            (VariantDef::get_discriminant): Replace return type to a reference
            instead of a reference to a unique pointer.
            (VariantDef::clone): Change to references.
            (VariantDef::monomorphized_clone): Likewise.
            (FnType::as_string): Likewise.
            (FnType::clone): Likewise.
            * typecheck/rust-tyty.h: Likewise.
            * util/rust-hir-map.cc (Mappings::insert_hir_impl_block): Likewise.
            * backend/rust-compile-asm.cc: Use a reference instead of the raw
            pointer value.
            * checks/errors/borrowck/rust-bir-builder-pattern.cc: Use references.
            * checks/errors/rust-hir-pattern-analysis.cc: Likewise.
    
    Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>

Diff:
---
 gcc/rust/backend/rust-compile-asm.cc               |   4 +-
 gcc/rust/backend/rust-compile-base.cc              |  35 +--
 gcc/rust/backend/rust-compile-base.h               |   2 +-
 gcc/rust/backend/rust-compile-block.cc             |  27 +-
 gcc/rust/backend/rust-compile-block.h              |   4 +-
 gcc/rust/backend/rust-compile-expr.cc              | 208 ++++++++-------
 gcc/rust/backend/rust-compile-expr.h               |   6 +-
 gcc/rust/backend/rust-compile-fnparam.cc           |  14 +-
 gcc/rust/backend/rust-compile-fnparam.h            |   4 +-
 gcc/rust/backend/rust-compile-implitem.cc          |   4 +-
 gcc/rust/backend/rust-compile-intrinsic.cc         |   2 +-
 gcc/rust/backend/rust-compile-item.cc              |   9 +-
 gcc/rust/backend/rust-compile-pattern.cc           |  77 +++---
 gcc/rust/backend/rust-compile-pattern.h            |   8 +-
 gcc/rust/backend/rust-compile-resolve-path.cc      |   4 +-
 gcc/rust/backend/rust-compile-stmt.cc              |  12 +-
 gcc/rust/backend/rust-compile-struct-field-expr.cc |  16 +-
 gcc/rust/backend/rust-compile-struct-field-expr.h  |   2 +-
 gcc/rust/backend/rust-compile-type.cc              |   2 +-
 gcc/rust/backend/rust-compile-var-decl.h           |   4 +-
 gcc/rust/backend/rust-compile.cc                   |  10 +-
 gcc/rust/backend/rust-mangle-v0.cc                 |   4 +-
 .../errors/borrowck/rust-bir-builder-expr-stmt.cc  | 119 ++++-----
 .../borrowck/rust-bir-builder-lazyboolexpr.h       |   8 +-
 .../errors/borrowck/rust-bir-builder-pattern.cc    |  20 +-
 .../errors/borrowck/rust-bir-builder-pattern.h     |   1 +
 .../errors/borrowck/rust-bir-builder-struct.h      |   4 +-
 gcc/rust/checks/errors/borrowck/rust-bir-builder.h |  16 +-
 .../errors/borrowck/rust-function-collector.h      |   4 +-
 .../checks/errors/privacy/rust-privacy-reporter.cc | 130 +++++-----
 .../checks/errors/privacy/rust-privacy-reporter.h  |   2 +-
 .../checks/errors/privacy/rust-reachability.cc     |   2 +-
 gcc/rust/checks/errors/rust-const-checker.cc       | 122 ++++-----
 .../checks/errors/rust-hir-pattern-analysis.cc     | 203 +++++++--------
 gcc/rust/checks/errors/rust-unsafe-checker.cc      | 118 ++++-----
 gcc/rust/checks/lints/rust-lint-marklive.cc        |  16 +-
 gcc/rust/checks/lints/rust-lint-marklive.h         |  72 +++---
 gcc/rust/hir/rust-hir-dump.cc                      |  34 +--
 gcc/rust/hir/tree/rust-hir-expr.h                  | 117 ++++-----
 gcc/rust/hir/tree/rust-hir-item.h                  |  59 +++--
 gcc/rust/hir/tree/rust-hir-path.h                  |  21 +-
 gcc/rust/hir/tree/rust-hir-pattern.h               |  18 +-
 gcc/rust/hir/tree/rust-hir-stmt.h                  |   8 +-
 gcc/rust/hir/tree/rust-hir-type.h                  |  18 +-
 gcc/rust/hir/tree/rust-hir.h                       |   7 +-
 gcc/rust/typecheck/rust-autoderef.cc               |   2 +-
 gcc/rust/typecheck/rust-hir-dot-operator.cc        | 179 +++++++------
 .../typecheck/rust-hir-inherent-impl-overlap.h     |   2 +-
 gcc/rust/typecheck/rust-hir-path-probe.cc          |   5 +-
 gcc/rust/typecheck/rust-hir-trait-resolve.cc       |   9 +-
 gcc/rust/typecheck/rust-hir-type-check-base.cc     |  30 +--
 gcc/rust/typecheck/rust-hir-type-check-base.h      |  10 +-
 gcc/rust/typecheck/rust-hir-type-check-enumitem.cc |  58 ++---
 gcc/rust/typecheck/rust-hir-type-check-enumitem.h  |   2 +-
 gcc/rust/typecheck/rust-hir-type-check-expr.cc     | 281 ++++++++++-----------
 gcc/rust/typecheck/rust-hir-type-check-expr.h      |   2 +-
 gcc/rust/typecheck/rust-hir-type-check-implitem.cc | 103 ++++----
 gcc/rust/typecheck/rust-hir-type-check-implitem.h  |  14 +-
 gcc/rust/typecheck/rust-hir-type-check-item.cc     |  79 +++---
 gcc/rust/typecheck/rust-hir-type-check-path.cc     |  12 +-
 gcc/rust/typecheck/rust-hir-type-check-pattern.cc  |  73 +++---
 gcc/rust/typecheck/rust-hir-type-check-pattern.h   |  11 +-
 gcc/rust/typecheck/rust-hir-type-check-stmt.cc     |  39 ++-
 gcc/rust/typecheck/rust-hir-type-check-stmt.h      |   2 +-
 .../typecheck/rust-hir-type-check-struct-field.h   |   4 +-
 gcc/rust/typecheck/rust-hir-type-check-struct.cc   |  22 +-
 gcc/rust/typecheck/rust-hir-type-check-type.cc     | 137 +++++-----
 gcc/rust/typecheck/rust-hir-type-check-type.h      |   6 +-
 gcc/rust/typecheck/rust-hir-type-check.cc          |  43 ++--
 gcc/rust/typecheck/rust-hir-type-check.h           |   2 +-
 gcc/rust/typecheck/rust-type-util.cc               |   5 +-
 gcc/rust/typecheck/rust-typecheck-context.cc       |   4 +-
 gcc/rust/typecheck/rust-tyty-bounds.cc             |  31 +--
 gcc/rust/typecheck/rust-tyty-call.cc               |  19 +-
 gcc/rust/typecheck/rust-tyty-subst.cc              |   4 +-
 gcc/rust/typecheck/rust-tyty.cc                    |  51 ++--
 gcc/rust/typecheck/rust-tyty.h                     |  23 +-
 gcc/rust/util/rust-hir-map.cc                      |   2 +-
 78 files changed, 1382 insertions(+), 1461 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-asm.cc b/gcc/rust/backend/rust-compile-asm.cc
index be553a3e70f9..22498bc4ea0f 100644
--- a/gcc/rust/backend/rust-compile-asm.cc
+++ b/gcc/rust/backend/rust-compile-asm.cc
@@ -85,7 +85,7 @@ CompileAsm::asm_construct_outputs (HIR::InlineAsm &expr)
 	{
 	  auto out = output.get_out ();
 
-	  tree out_tree = CompileExpr::Compile (out.expr.get (), this->ctx);
+	  tree out_tree = CompileExpr::Compile (*out.expr, this->ctx);
 	  // expects a tree list
 	  // TODO: This assumes that the output is a register
 	  std::string expr_name = "=r";
@@ -112,7 +112,7 @@ CompileAsm::asm_construct_inputs (HIR::InlineAsm &expr)
 	{
 	  auto in = input.get_in ();
 
-	  tree in_tree = CompileExpr::Compile (in.expr.get (), this->ctx);
+	  tree in_tree = CompileExpr::Compile (*in.expr, this->ctx);
 	  // expects a tree list
 	  // TODO: This assumes that the input is a register
 	  std::string expr_name = "r";
diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc
index 8166c3ae224c..598f2e2e451b 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -582,8 +582,9 @@ HIRCompileBase::compile_function_body (tree fndecl,
 
   if (function_body.has_expr ())
     {
-      location_t locus = function_body.get_final_expr ()->get_locus ();
-      tree return_value = CompileExpr::Compile (function_body.expr.get (), ctx);
+      location_t locus = function_body.get_final_expr ().get_locus ();
+      tree return_value
+	= CompileExpr::Compile (function_body.get_final_expr (), ctx);
 
       // we can only return this if non unit value return type
       if (!fn_return_ty->is_unit ())
@@ -709,18 +710,18 @@ HIRCompileBase::compile_function (
   size_t i = is_method ? 1 : 0;
   for (auto &referenced_param : function_params)
     {
-      auto tyty_param = fntype->param_at (i++);
+      auto &tyty_param = fntype->param_at (i++);
       auto param_tyty = tyty_param.second;
       auto compiled_param_type = TyTyResolveCompile::compile (ctx, param_tyty);
 
       location_t param_locus = referenced_param.get_locus ();
       Bvariable *compiled_param_var
-	= CompileFnParam::compile (ctx, fndecl, &referenced_param,
+	= CompileFnParam::compile (ctx, fndecl, referenced_param,
 				   compiled_param_type, param_locus);
 
       param_vars.push_back (compiled_param_var);
 
-      const HIR::Pattern &param_pattern = *referenced_param.get_param_name ();
+      const HIR::Pattern &param_pattern = referenced_param.get_param_name ();
       ctx->insert_var_decl (param_pattern.get_mappings ().get_hirid (),
 			    compiled_param_var);
     }
@@ -768,14 +769,14 @@ HIRCompileBase::compile_function (
 tree
 HIRCompileBase::compile_constant_item (
   TyTy::BaseType *resolved_type, const Resolver::CanonicalPath &canonical_path,
-  HIR::Expr *const_value_expr, location_t locus)
+  HIR::Expr &const_value_expr, location_t 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;
+    = const_value_expr.get_expression_type () == HIR::Expr::ExprType::Block;
 
   // 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
@@ -789,14 +790,14 @@ HIRCompileBase::compile_constant_item (
   TREE_READONLY (fndecl) = 1;
 
   tree enclosing_scope = NULL_TREE;
-  location_t start_location = const_value_expr->get_locus ();
-  location_t end_location = const_value_expr->get_locus ();
+  location_t start_location = const_value_expr.get_locus ();
+  location_t end_location = const_value_expr.get_locus ();
   if (is_block_expr)
     {
-      HIR::BlockExpr *function_body
-	= static_cast<HIR::BlockExpr *> (const_value_expr);
-      start_location = function_body->get_locus ();
-      end_location = function_body->get_end_locus ();
+      HIR::BlockExpr &function_body
+	= static_cast<HIR::BlockExpr &> (const_value_expr);
+      start_location = function_body.get_locus ();
+      end_location = function_body.get_end_locus ();
     }
 
   tree code_block = Backend::block (fndecl, enclosing_scope, {} /*locals*/,
@@ -814,9 +815,9 @@ HIRCompileBase::compile_constant_item (
 
   if (is_block_expr)
     {
-      HIR::BlockExpr *function_body
-	= static_cast<HIR::BlockExpr *> (const_value_expr);
-      compile_function_body (fndecl, *function_body, resolved_type);
+      HIR::BlockExpr &function_body
+	= static_cast<HIR::BlockExpr &> (const_value_expr);
+      compile_function_body (fndecl, function_body, resolved_type);
     }
   else
     {
@@ -824,7 +825,7 @@ HIRCompileBase::compile_constant_item (
 
       tree return_expr
 	= Backend::return_statement (fndecl, value,
-				     const_value_expr->get_locus ());
+				     const_value_expr.get_locus ());
       ctx->add_statement (return_expr);
     }
 
diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h
index eeb3ff026193..5fb1d83f2eeb 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -92,7 +92,7 @@ protected:
 
   tree compile_constant_item (TyTy::BaseType *resolved_type,
 			      const Resolver::CanonicalPath &canonical_path,
-			      HIR::Expr *const_value_expr, location_t locus);
+			      HIR::Expr &const_value_expr, location_t locus);
 
   tree compile_function (const std::string &fn_name, HIR::SelfParam &self_param,
 			 std::vector<HIR::FunctionParam> &function_params,
diff --git a/gcc/rust/backend/rust-compile-block.cc b/gcc/rust/backend/rust-compile-block.cc
index eb8af2a0d3be..f844a27e9890 100644
--- a/gcc/rust/backend/rust-compile-block.cc
+++ b/gcc/rust/backend/rust-compile-block.cc
@@ -28,10 +28,10 @@ CompileBlock::CompileBlock (Context *ctx, Bvariable *result)
 {}
 
 tree
-CompileBlock::compile (HIR::BlockExpr *expr, Context *ctx, Bvariable *result)
+CompileBlock::compile (HIR::BlockExpr &expr, Context *ctx, Bvariable *result)
 {
   CompileBlock compiler (ctx, result);
-  compiler.visit (*expr);
+  compiler.visit (expr);
   return compiler.translated;
 }
 
@@ -60,10 +60,10 @@ CompileBlock::visit (HIR::BlockExpr &expr)
 
   if (expr.has_expr ())
     {
-      tree compiled_expr = CompileExpr::Compile (expr.expr.get (), ctx);
+      tree compiled_expr = CompileExpr::Compile (expr.get_final_expr (), ctx);
       if (result != nullptr)
 	{
-	  location_t locus = expr.get_final_expr ()->get_locus ();
+	  location_t locus = expr.get_final_expr ().get_locus ();
 	  tree result_reference = Backend::var_expression (result, locus);
 
 	  tree assignment
@@ -93,10 +93,8 @@ CompileConditionalBlocks::visit (HIR::IfExpr &expr)
 {
   fncontext fnctx = ctx->peek_fn ();
   tree fndecl = fnctx.fndecl;
-  tree condition_expr
-    = CompileExpr::Compile (expr.get_if_condition ().get (), ctx);
-  tree then_block
-    = CompileBlock::compile (expr.get_if_block ().get (), ctx, result);
+  tree condition_expr = CompileExpr::Compile (expr.get_if_condition (), ctx);
+  tree then_block = CompileBlock::compile (expr.get_if_block (), ctx, result);
 
   translated = Backend::if_statement (fndecl, condition_expr, then_block, NULL,
 				      expr.get_locus ());
@@ -107,23 +105,20 @@ CompileConditionalBlocks::visit (HIR::IfExprConseqElse &expr)
 {
   fncontext fnctx = ctx->peek_fn ();
   tree fndecl = fnctx.fndecl;
-  tree condition_expr
-    = CompileExpr::Compile (expr.get_if_condition ().get (), ctx);
-  tree then_block
-    = CompileBlock::compile (expr.get_if_block ().get (), ctx, result);
+  tree condition_expr = CompileExpr::Compile (expr.get_if_condition (), ctx);
+  tree then_block = CompileBlock::compile (expr.get_if_block (), ctx, result);
 
   // else block
   std::vector<Bvariable *> locals;
-  location_t start_location = expr.get_else_block ()->get_locus ();
-  location_t end_location = expr.get_else_block ()->get_locus (); // FIXME
+  location_t start_location = expr.get_else_block ().get_locus ();
+  location_t end_location = expr.get_else_block ().get_locus (); // FIXME
   tree enclosing_scope = ctx->peek_enclosing_scope ();
   tree else_block = Backend::block (fndecl, enclosing_scope, locals,
 				    start_location, end_location);
   ctx->push_block (else_block);
 
   tree else_stmt_decl
-    = CompileExprWithBlock::compile (expr.get_else_block ().get (), ctx,
-				     result);
+    = CompileExprWithBlock::compile (&expr.get_else_block (), ctx, result);
 
   ctx->add_statement (else_stmt_decl);
 
diff --git a/gcc/rust/backend/rust-compile-block.h b/gcc/rust/backend/rust-compile-block.h
index 6616882894f0..37e3980bd6cd 100644
--- a/gcc/rust/backend/rust-compile-block.h
+++ b/gcc/rust/backend/rust-compile-block.h
@@ -28,7 +28,7 @@ namespace Compile {
 class CompileBlock : private HIRCompileBase
 {
 public:
-  static tree compile (HIR::BlockExpr *expr, Context *ctx, Bvariable *result);
+  static tree compile (HIR::BlockExpr &expr, Context *ctx, Bvariable *result);
 
 protected:
   void visit (HIR::BlockExpr &expr);
@@ -134,7 +134,7 @@ public:
 
   void visit (HIR::BlockExpr &expr) override
   {
-    translated = CompileBlock::compile (&expr, ctx, result);
+    translated = CompileBlock::compile (expr, ctx, result);
   }
 
   // Empty visit for unused Expression HIR nodes.
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index 7251cc82d6ed..c46bda954adf 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -40,24 +40,24 @@ CompileExpr::CompileExpr (Context *ctx)
 {}
 
 tree
-CompileExpr::Compile (HIR::Expr *expr, Context *ctx)
+CompileExpr::Compile (HIR::Expr &expr, Context *ctx)
 {
   CompileExpr compiler (ctx);
-  expr->accept_vis (compiler);
+  expr.accept_vis (compiler);
   return compiler.translated;
 }
 
 void
 CompileExpr::visit (HIR::TupleIndexExpr &expr)
 {
-  HIR::Expr *tuple_expr = expr.get_tuple_expr ().get ();
+  HIR::Expr &tuple_expr = expr.get_tuple_expr ();
   TupleIndex index = expr.get_tuple_index ();
 
   tree receiver_ref = CompileExpr::Compile (tuple_expr, ctx);
 
   TyTy::BaseType *tuple_expr_ty = nullptr;
   bool ok
-    = ctx->get_tyctx ()->lookup_type (tuple_expr->get_mappings ().get_hirid (),
+    = ctx->get_tyctx ()->lookup_type (tuple_expr.get_mappings ().get_hirid (),
 				      &tuple_expr_ty);
   rust_assert (ok);
 
@@ -97,7 +97,7 @@ CompileExpr::visit (HIR::TupleExpr &expr)
   std::vector<tree> vals;
   for (auto &elem : expr.get_tuple_elems ())
     {
-      auto e = CompileExpr::Compile (elem.get (), ctx);
+      auto e = CompileExpr::Compile (*elem, ctx);
       vals.push_back (e);
     }
 
@@ -111,7 +111,7 @@ CompileExpr::visit (HIR::ReturnExpr &expr)
   auto fncontext = ctx->peek_fn ();
 
   tree return_value = expr.has_return_expr ()
-			? CompileExpr::Compile (expr.return_expr.get (), ctx)
+			? CompileExpr::Compile (expr.get_expr (), ctx)
 			: unit_expression (expr.get_locus ());
 
   if (expr.has_return_expr ())
@@ -141,8 +141,8 @@ void
 CompileExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
 {
   auto op = expr.get_expr_type ();
-  auto lhs = CompileExpr::Compile (expr.get_lhs ().get (), ctx);
-  auto rhs = CompileExpr::Compile (expr.get_rhs ().get (), ctx);
+  auto lhs = CompileExpr::Compile (expr.get_lhs (), ctx);
+  auto rhs = CompileExpr::Compile (expr.get_rhs (), ctx);
 
   // this might be an operator overload situation lets check
   TyTy::FnType *fntype;
@@ -153,8 +153,7 @@ CompileExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
       auto lang_item_type
 	= LangItem::OperatorToLangItem (expr.get_expr_type ());
       translated = resolve_operator_overload (lang_item_type, expr, lhs, rhs,
-					      expr.get_lhs ().get (),
-					      expr.get_rhs ().get ());
+					      expr.get_lhs (), expr.get_rhs ());
       return;
     }
 
@@ -185,8 +184,8 @@ void
 CompileExpr::visit (HIR::CompoundAssignmentExpr &expr)
 {
   auto op = expr.get_expr_type ();
-  auto lhs = CompileExpr::Compile (expr.get_lhs ().get (), ctx);
-  auto rhs = CompileExpr::Compile (expr.get_rhs ().get (), ctx);
+  auto lhs = CompileExpr::Compile (expr.get_lhs (), ctx);
+  auto rhs = CompileExpr::Compile (expr.get_rhs (), ctx);
 
   // this might be an operator overload situation lets check
   TyTy::FnType *fntype;
@@ -198,8 +197,7 @@ CompileExpr::visit (HIR::CompoundAssignmentExpr &expr)
 	expr.get_expr_type ());
       auto compound_assignment
 	= resolve_operator_overload (lang_item_type, expr, lhs, rhs,
-				     expr.get_lhs ().get (),
-				     expr.get_rhs ().get ());
+				     expr.get_lhs (), expr.get_rhs ());
       ctx->add_statement (compound_assignment);
 
       return;
@@ -236,18 +234,18 @@ CompileExpr::visit (HIR::NegationExpr &expr)
 {
   auto op = expr.get_expr_type ();
 
-  const auto literal_expr = expr.get_expr ().get ();
+  auto &literal_expr = expr.get_expr ();
 
   // If it's a negated integer/float literal, we can return early
   if (op == NegationOperator::NEGATE
-      && literal_expr->get_expression_type () == HIR::Expr::ExprType::Lit)
+      && literal_expr.get_expression_type () == HIR::Expr::ExprType::Lit)
     {
-      auto new_literal_expr = static_cast<HIR::LiteralExpr *> (literal_expr);
-      auto lit_type = new_literal_expr->get_lit_type ();
+      auto &new_literal_expr = static_cast<HIR::LiteralExpr &> (literal_expr);
+      auto lit_type = new_literal_expr.get_lit_type ();
       if (lit_type == HIR::Literal::LitType::INT
 	  || lit_type == HIR::Literal::LitType::FLOAT)
 	{
-	  new_literal_expr->set_negative ();
+	  new_literal_expr.set_negative ();
 	  translated = CompileExpr::Compile (literal_expr, ctx);
 	  return;
 	}
@@ -265,7 +263,7 @@ CompileExpr::visit (HIR::NegationExpr &expr)
       auto lang_item_type = LangItem::NegationOperatorToLangItem (op);
       translated
 	= resolve_operator_overload (lang_item_type, expr, negated_expr,
-				     nullptr, expr.get_expr ().get (), nullptr);
+				     nullptr, expr.get_expr (), tl::nullopt);
       return;
     }
 
@@ -276,8 +274,8 @@ void
 CompileExpr::visit (HIR::ComparisonExpr &expr)
 {
   auto op = expr.get_expr_type ();
-  auto lhs = CompileExpr::Compile (expr.get_lhs ().get (), ctx);
-  auto rhs = CompileExpr::Compile (expr.get_rhs ().get (), ctx);
+  auto lhs = CompileExpr::Compile (expr.get_lhs (), ctx);
+  auto rhs = CompileExpr::Compile (expr.get_rhs (), ctx);
   auto location = expr.get_locus ();
 
   translated = Backend::comparison_expression (op, lhs, rhs, location);
@@ -287,8 +285,8 @@ void
 CompileExpr::visit (HIR::LazyBooleanExpr &expr)
 {
   auto op = expr.get_expr_type ();
-  auto lhs = CompileExpr::Compile (expr.get_lhs ().get (), ctx);
-  auto rhs = CompileExpr::Compile (expr.get_rhs ().get (), ctx);
+  auto lhs = CompileExpr::Compile (expr.get_lhs (), ctx);
+  auto rhs = CompileExpr::Compile (expr.get_rhs (), ctx);
   auto location = expr.get_locus ();
 
   translated = Backend::lazy_boolean_expression (op, lhs, rhs, location);
@@ -307,14 +305,14 @@ CompileExpr::visit (HIR::TypeCastExpr &expr)
 
   TyTy::BaseType *casted_tyty = nullptr;
   if (!ctx->get_tyctx ()->lookup_type (
-	expr.get_casted_expr ()->get_mappings ().get_hirid (), &casted_tyty))
+	expr.get_casted_expr ().get_mappings ().get_hirid (), &casted_tyty))
     {
       translated = error_mark_node;
       return;
     }
 
   auto type_to_cast_to = TyTyResolveCompile::compile (ctx, type_to_cast_to_ty);
-  auto casted_expr = CompileExpr::Compile (expr.get_casted_expr ().get (), ctx);
+  auto casted_expr = CompileExpr::Compile (expr.get_casted_expr (), ctx);
 
   std::vector<Resolver::Adjustment> *adjustments = nullptr;
   bool ok = ctx->get_tyctx ()->lookup_cast_autoderef_mappings (
@@ -405,7 +403,7 @@ CompileExpr::visit (HIR::BlockExpr &expr)
 				     &ret_var_stmt);
   ctx->add_statement (ret_var_stmt);
 
-  auto block_stmt = CompileBlock::compile (&expr, ctx, tmp);
+  auto block_stmt = CompileBlock::compile (expr, ctx, tmp);
   rust_assert (TREE_CODE (block_stmt) == BIND_EXPR);
   ctx->add_statement (block_stmt);
 
@@ -415,7 +413,7 @@ CompileExpr::visit (HIR::BlockExpr &expr)
 void
 CompileExpr::visit (HIR::UnsafeBlockExpr &expr)
 {
-  expr.get_block_expr ()->accept_vis (*this);
+  expr.get_block_expr ().accept_vis (*this);
 }
 
 void
@@ -487,7 +485,7 @@ CompileExpr::visit (HIR::StructExprStructFields &struct_expr)
       auto lvalue_locus
 	= ctx->get_mappings ().lookup_location (expected->get_ty_ref ());
       auto rvalue_locus = argument->get_locus ();
-      auto rvalue = CompileStructExprField::Compile (argument.get (), ctx);
+      auto rvalue = CompileStructExprField::Compile (*argument, ctx);
 
       TyTy::BaseType *actual = nullptr;
       bool ok = ctx->get_tyctx ()->lookup_type (
@@ -519,7 +517,7 @@ CompileExpr::visit (HIR::StructExprStructFields &struct_expr)
 	  auto lvalue_locus
 	    = ctx->get_mappings ().lookup_location (expected->get_ty_ref ());
 	  auto rvalue_locus = argument->get_locus ();
-	  auto rvalue = CompileStructExprField::Compile (argument.get (), ctx);
+	  auto rvalue = CompileStructExprField::Compile (*argument, ctx);
 
 	  TyTy::BaseType *actual = nullptr;
 	  bool ok = ctx->get_tyctx ()->lookup_type (
@@ -544,7 +542,7 @@ CompileExpr::visit (HIR::StructExprStructFields &struct_expr)
   std::vector<tree> ctor_arguments;
   if (adt->is_enum ())
     {
-      HIR::Expr *discrim_expr = variant->get_discriminant ();
+      HIR::Expr &discrim_expr = variant->get_discriminant ();
       tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
       tree folded_discrim_expr = fold_expr (discrim_expr_node);
       tree qualifier = folded_discrim_expr;
@@ -563,21 +561,21 @@ CompileExpr::visit (HIR::StructExprStructFields &struct_expr)
 void
 CompileExpr::visit (HIR::GroupedExpr &expr)
 {
-  translated = CompileExpr::Compile (expr.get_expr_in_parens ().get (), ctx);
+  translated = CompileExpr::Compile (expr.get_expr_in_parens (), ctx);
 }
 
 void
 CompileExpr::visit (HIR::FieldAccessExpr &expr)
 {
-  HIR::Expr *receiver_expr = expr.get_receiver_expr ().get ();
+  HIR::Expr &receiver_expr = expr.get_receiver_expr ();
   tree receiver_ref = CompileExpr::Compile (receiver_expr, ctx);
 
   // resolve the receiver back to ADT type
   TyTy::BaseType *receiver = nullptr;
   if (!ctx->get_tyctx ()->lookup_type (
-	expr.get_receiver_expr ()->get_mappings ().get_hirid (), &receiver))
+	expr.get_receiver_expr ().get_mappings ().get_hirid (), &receiver))
     {
-      rust_error_at (expr.get_receiver_expr ()->get_locus (),
+      rust_error_at (expr.get_receiver_expr ().get_locus (),
 		     "unresolved type for receiver");
       return;
     }
@@ -672,7 +670,7 @@ CompileExpr::visit (HIR::LoopExpr &expr)
   ctx->push_loop_begin_label (loop_begin_label);
 
   tree code_block
-    = CompileBlock::compile (expr.get_loop_block ().get (), ctx, nullptr);
+    = CompileBlock::compile (expr.get_loop_block (), ctx, nullptr);
   tree loop_expr = Backend::loop_expression (code_block, expr.get_locus ());
   ctx->add_statement (loop_expr);
 
@@ -699,8 +697,8 @@ CompileExpr::visit (HIR::WhileLoopExpr &expr)
     }
 
   std::vector<Bvariable *> locals;
-  location_t start_location = expr.get_loop_block ()->get_locus ();
-  location_t end_location = expr.get_loop_block ()->get_locus (); // FIXME
+  location_t start_location = expr.get_loop_block ().get_locus ();
+  location_t end_location = expr.get_loop_block ().get_locus (); // FIXME
 
   tree enclosing_scope = ctx->peek_enclosing_scope ();
   tree loop_block = Backend::block (fnctx.fndecl, enclosing_scope, locals,
@@ -713,15 +711,14 @@ CompileExpr::visit (HIR::WhileLoopExpr &expr)
   ctx->add_statement (loop_begin_label_decl);
   ctx->push_loop_begin_label (loop_begin_label);
 
-  tree condition
-    = CompileExpr::Compile (expr.get_predicate_expr ().get (), ctx);
+  tree condition = CompileExpr::Compile (expr.get_predicate_expr (), ctx);
   tree exit_condition = fold_build1_loc (expr.get_locus (), TRUTH_NOT_EXPR,
 					 boolean_type_node, condition);
   tree exit_expr = Backend::exit_expression (exit_condition, expr.get_locus ());
   ctx->add_statement (exit_expr);
 
   tree code_block_stmt
-    = CompileBlock::compile (expr.get_loop_block ().get (), ctx, nullptr);
+    = CompileBlock::compile (expr.get_loop_block (), ctx, nullptr);
   rust_assert (TREE_CODE (code_block_stmt) == BIND_EXPR);
   ctx->add_statement (code_block_stmt);
 
@@ -737,12 +734,12 @@ CompileExpr::visit (HIR::BreakExpr &expr)
 {
   if (expr.has_break_expr ())
     {
-      tree compiled_expr = CompileExpr::Compile (expr.get_expr ().get (), ctx);
+      tree compiled_expr = CompileExpr::Compile (expr.get_expr (), ctx);
 
       Bvariable *loop_result_holder = ctx->peek_loop_context ();
       tree result_reference
 	= Backend::var_expression (loop_result_holder,
-				   expr.get_expr ()->get_locus ());
+				   expr.get_expr ().get_locus ());
 
       tree assignment
 	= Backend::assignment_statement (result_reference, compiled_expr,
@@ -865,7 +862,7 @@ CompileExpr::visit (HIR::ContinueExpr &expr)
 void
 CompileExpr::visit (HIR::BorrowExpr &expr)
 {
-  tree main_expr = CompileExpr::Compile (expr.get_expr ().get (), ctx);
+  tree main_expr = CompileExpr::Compile (expr.get_expr (), ctx);
   if (RS_DST_FLAG_P (TREE_TYPE (main_expr)))
     {
       translated = main_expr;
@@ -892,7 +889,7 @@ CompileExpr::visit (HIR::DereferenceExpr &expr)
       return;
     }
 
-  tree main_expr = CompileExpr::Compile (expr.get_expr ().get (), ctx);
+  tree main_expr = CompileExpr::Compile (expr.get_expr (), ctx);
 
   // this might be an operator overload situation lets check
   TyTy::FnType *fntype;
@@ -903,7 +900,7 @@ CompileExpr::visit (HIR::DereferenceExpr &expr)
       auto lang_item_type = LangItem::Kind::DEREF;
       tree operator_overload_call
 	= resolve_operator_overload (lang_item_type, expr, main_expr, nullptr,
-				     expr.get_expr ().get (), nullptr);
+				     expr.get_expr (), tl::nullopt);
 
       // rust deref always returns a reference from this overload then we can
       // actually do the indirection
@@ -963,8 +960,8 @@ CompileExpr::visit (HIR::LiteralExpr &expr)
 void
 CompileExpr::visit (HIR::AssignmentExpr &expr)
 {
-  auto lvalue = CompileExpr::Compile (expr.get_lhs ().get (), ctx);
-  auto rvalue = CompileExpr::Compile (expr.get_rhs ().get (), ctx);
+  auto lvalue = CompileExpr::Compile (expr.get_lhs (), ctx);
+  auto rvalue = CompileExpr::Compile (expr.get_rhs (), ctx);
 
   // assignments are coercion sites so lets convert the rvalue if necessary
   TyTy::BaseType *expected = nullptr;
@@ -972,16 +969,16 @@ CompileExpr::visit (HIR::AssignmentExpr &expr)
 
   bool ok;
   ok = ctx->get_tyctx ()->lookup_type (
-    expr.get_lhs ()->get_mappings ().get_hirid (), &expected);
+    expr.get_lhs ().get_mappings ().get_hirid (), &expected);
   rust_assert (ok);
 
   ok = ctx->get_tyctx ()->lookup_type (
-    expr.get_rhs ()->get_mappings ().get_hirid (), &actual);
+    expr.get_rhs ().get_mappings ().get_hirid (), &actual);
   rust_assert (ok);
 
   rvalue = coercion_site (expr.get_mappings ().get_hirid (), rvalue, actual,
-			  expected, expr.get_lhs ()->get_locus (),
-			  expr.get_rhs ()->get_locus ());
+			  expected, expr.get_lhs ().get_locus (),
+			  expr.get_rhs ().get_locus ());
 
   // rust_debug_loc (expr.get_locus (), "XXXXXX assignment");
   // debug_tree (rvalue);
@@ -1002,7 +999,7 @@ check_match_scrutinee (HIR::MatchExpr &expr, Context *ctx)
 {
   TyTy::BaseType *scrutinee_expr_tyty = nullptr;
   if (!ctx->get_tyctx ()->lookup_type (
-	expr.get_scrutinee_expr ()->get_mappings ().get_hirid (),
+	expr.get_scrutinee_expr ().get_mappings ().get_hirid (),
 	&scrutinee_expr_tyty))
     {
       return TyTy::TypeKind::ERROR;
@@ -1080,7 +1077,7 @@ CompileExpr::visit (HIR::MatchExpr &expr)
 
   // lets compile the scrutinee expression
   tree match_scrutinee_rval
-    = CompileExpr::Compile (expr.get_scrutinee_expr ().get (), ctx);
+    = CompileExpr::Compile (expr.get_scrutinee_expr (), ctx);
 
   Bvariable *match_scrutinee_tmp_var
     = Backend::temporary_variable (fnctx.fndecl, enclosing_scope,
@@ -1090,7 +1087,7 @@ CompileExpr::visit (HIR::MatchExpr &expr)
   ctx->add_statement (ret_var_stmt);
 
   tree match_scrutinee_expr = match_scrutinee_tmp_var->get_tree (
-    expr.get_scrutinee_expr ()->get_locus ());
+    expr.get_scrutinee_expr ().get_locus ());
 
   tree assignment
     = Backend::assignment_statement (match_scrutinee_expr, match_scrutinee_rval,
@@ -1123,14 +1120,13 @@ CompileExpr::visit (HIR::MatchExpr &expr)
 	  ctx->push_block (arm_body_block);
 
 	  // setup the bindings for the block
-	  CompilePatternBindings::Compile (kase_pattern.get (),
-					   match_scrutinee_expr, ctx);
+	  CompilePatternBindings::Compile (*kase_pattern, match_scrutinee_expr,
+					   ctx);
 
 	  // compile the expr and setup the assignment if required when tmp !=
 	  // NULL
 	  location_t arm_locus = kase_arm.get_locus ();
-	  tree kase_expr_tree
-	    = CompileExpr::Compile (kase.get_expr ().get (), ctx);
+	  tree kase_expr_tree = CompileExpr::Compile (kase.get_expr (), ctx);
 	  tree result_reference = Backend::var_expression (tmp, arm_locus);
 	  tree assignment
 	    = Backend::assignment_statement (result_reference, kase_expr_tree,
@@ -1145,7 +1141,7 @@ CompileExpr::visit (HIR::MatchExpr &expr)
 	  ctx->pop_block ();
 
 	  tree check_expr
-	    = CompilePatternCheckExpr::Compile (kase_pattern.get (),
+	    = CompilePatternCheckExpr::Compile (*kase_pattern,
 						match_scrutinee_expr, ctx);
 
 	  tree check_stmt
@@ -1167,7 +1163,7 @@ CompileExpr::visit (HIR::CallExpr &expr)
 {
   TyTy::BaseType *tyty = nullptr;
   if (!ctx->get_tyctx ()->lookup_type (
-	expr.get_fnexpr ()->get_mappings ().get_hirid (), &tyty))
+	expr.get_fnexpr ().get_mappings ().get_hirid (), &tyty))
     {
       rust_error_at (expr.get_locus (), "unknown type");
       return;
@@ -1193,7 +1189,7 @@ CompileExpr::visit (HIR::CallExpr &expr)
 	{
 	  HirId variant_id;
 	  bool ok = ctx->get_tyctx ()->lookup_variant_definition (
-	    expr.get_fnexpr ()->get_mappings ().get_hirid (), &variant_id);
+	    expr.get_fnexpr ().get_mappings ().get_hirid (), &variant_id);
 	  rust_assert (ok);
 
 	  ok = adt->lookup_variant_by_id (variant_id, &variant,
@@ -1207,7 +1203,7 @@ CompileExpr::visit (HIR::CallExpr &expr)
       for (size_t i = 0; i < expr.get_arguments ().size (); i++)
 	{
 	  auto &argument = expr.get_arguments ().at (i);
-	  auto rvalue = CompileExpr::Compile (argument.get (), ctx);
+	  auto rvalue = CompileExpr::Compile (*argument, ctx);
 
 	  // assignments are coercion sites so lets convert the rvalue if
 	  // necessary
@@ -1236,7 +1232,7 @@ CompileExpr::visit (HIR::CallExpr &expr)
       std::vector<tree> ctor_arguments;
       if (adt->is_enum ())
 	{
-	  HIR::Expr *discrim_expr = variant->get_discriminant ();
+	  HIR::Expr &discrim_expr = variant->get_discriminant ();
 	  tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
 	  tree folded_discrim_expr = fold_expr (discrim_expr_node);
 	  tree qualifier = folded_discrim_expr;
@@ -1270,13 +1266,13 @@ CompileExpr::visit (HIR::CallExpr &expr)
       }
 
     const TyTy::FnType *fn = static_cast<const TyTy::FnType *> (base);
-    auto param = fn->param_at (index);
+    auto &param = fn->param_at (index);
     *result = param.second;
 
     return true;
   };
 
-  auto fn_address = CompileExpr::Compile (expr.get_fnexpr ().get (), ctx);
+  auto fn_address = CompileExpr::Compile (expr.get_fnexpr (), ctx);
 
   // is this a closure call?
   bool possible_trait_call
@@ -1303,7 +1299,7 @@ CompileExpr::visit (HIR::CallExpr &expr)
   for (size_t i = 0; i < expr.get_arguments ().size (); i++)
     {
       auto &argument = expr.get_arguments ().at (i);
-      auto rvalue = CompileExpr::Compile (argument.get (), ctx);
+      auto rvalue = CompileExpr::Compile (*argument, ctx);
 
       if (is_variadic && i >= required_num_args)
 	{
@@ -1343,7 +1339,7 @@ void
 CompileExpr::visit (HIR::MethodCallExpr &expr)
 {
   // method receiver
-  tree self = CompileExpr::Compile (expr.get_receiver ().get (), ctx);
+  tree self = CompileExpr::Compile (expr.get_receiver (), ctx);
 
   // lookup the expected function type
   TyTy::BaseType *lookup_fntype = nullptr;
@@ -1383,7 +1379,7 @@ CompileExpr::visit (HIR::MethodCallExpr &expr)
 
   // lookup the autoderef mappings
   HirId autoderef_mappings_id
-    = expr.get_receiver ()->get_mappings ().get_hirid ();
+    = expr.get_receiver ().get_mappings ().get_hirid ();
   std::vector<Resolver::Adjustment> *adjustments = nullptr;
   ok = ctx->get_tyctx ()->lookup_autoderef_mappings (autoderef_mappings_id,
 						     &adjustments);
@@ -1391,7 +1387,7 @@ CompileExpr::visit (HIR::MethodCallExpr &expr)
 
   // apply adjustments for the fn call
   self = resolve_adjustements (*adjustments, self,
-			       expr.get_receiver ()->get_locus ());
+			       expr.get_receiver ().get_locus ());
 
   std::vector<tree> args;
   args.push_back (self); // adjusted self
@@ -1400,7 +1396,7 @@ CompileExpr::visit (HIR::MethodCallExpr &expr)
   for (size_t i = 0; i < expr.get_arguments ().size (); i++)
     {
       auto &argument = expr.get_arguments ().at (i);
-      auto rvalue = CompileExpr::Compile (argument.get (), ctx);
+      auto rvalue = CompileExpr::Compile (*argument, ctx);
 
       // assignments are coercion sites so lets convert the rvalue if
       // necessary, offset from the already adjusted implicit self
@@ -1482,8 +1478,8 @@ CompileExpr::get_receiver_from_dyn (const TyTy::DynamicObjectType *dyn,
 tree
 CompileExpr::resolve_operator_overload (LangItem::Kind lang_item_type,
 					HIR::OperatorExprMeta expr, tree lhs,
-					tree rhs, HIR::Expr *lhs_expr,
-					HIR::Expr *rhs_expr)
+					tree rhs, HIR::Expr &lhs_expr,
+					tl::optional<HIR::Expr &> rhs_expr)
 {
   TyTy::FnType *fntype;
   bool is_op_overload = ctx->get_tyctx ()->lookup_operator_overload (
@@ -1514,7 +1510,7 @@ CompileExpr::resolve_operator_overload (LangItem::Kind lang_item_type,
   rust_assert (ok);
 
   // apply adjustments for the fn call
-  tree self = resolve_adjustements (*adjustments, lhs, lhs_expr->get_locus ());
+  tree self = resolve_adjustements (*adjustments, lhs, lhs_expr.get_locus ());
 
   std::vector<tree> args;
   args.push_back (self); // adjusted self
@@ -1829,7 +1825,7 @@ CompileExpr::visit (HIR::ArrayExpr &expr)
   const TyTy::ArrayType &array_tyty
     = static_cast<const TyTy::ArrayType &> (*tyty);
 
-  HIR::ArrayElems &elements = *expr.get_internal_elements ();
+  HIR::ArrayElems &elements = expr.get_internal_elements ();
   switch (elements.get_array_expr_type ())
     {
       case HIR::ArrayElems::ArrayExprType::VALUES: {
@@ -1858,7 +1854,7 @@ CompileExpr::array_value_expr (location_t expr_locus,
   size_t i = 0;
   for (auto &elem : elems.get_values ())
     {
-      tree translated_expr = CompileExpr::Compile (elem.get (), ctx);
+      tree translated_expr = CompileExpr::Compile (*elem, ctx);
       constructor.push_back (translated_expr);
       indexes.push_back (i++);
     }
@@ -1885,8 +1881,7 @@ CompileExpr::array_copied_expr (location_t expr_locus,
     }
 
   ctx->push_const_context ();
-  tree capacity_expr
-    = CompileExpr::Compile (elems.get_num_copies_expr ().get (), ctx);
+  tree capacity_expr = CompileExpr::Compile (elems.get_num_copies_expr (), ctx);
   ctx->pop_const_context ();
 
   if (!TREE_CONSTANT (capacity_expr))
@@ -1896,8 +1891,7 @@ CompileExpr::array_copied_expr (location_t expr_locus,
     }
 
   // get the compiled value
-  tree translated_expr
-    = CompileExpr::Compile (elems.get_elem_to_copy ().get (), ctx);
+  tree translated_expr = CompileExpr::Compile (elems.get_elem_to_copy (), ctx);
 
   tree max_domain = TYPE_MAX_VALUE (domain);
   tree min_domain = TYPE_MIN_VALUE (domain);
@@ -2102,8 +2096,8 @@ HIRCompileBase::resolve_unsized_dyn_adjustment (
 void
 CompileExpr::visit (HIR::RangeFromToExpr &expr)
 {
-  tree from = CompileExpr::Compile (expr.get_from_expr ().get (), ctx);
-  tree to = CompileExpr::Compile (expr.get_to_expr ().get (), ctx);
+  tree from = CompileExpr::Compile (expr.get_from_expr (), ctx);
+  tree to = CompileExpr::Compile (expr.get_to_expr (), ctx);
   if (from == error_mark_node || to == error_mark_node)
     {
       translated = error_mark_node;
@@ -2125,7 +2119,7 @@ CompileExpr::visit (HIR::RangeFromToExpr &expr)
 void
 CompileExpr::visit (HIR::RangeFromExpr &expr)
 {
-  tree from = CompileExpr::Compile (expr.get_from_expr ().get (), ctx);
+  tree from = CompileExpr::Compile (expr.get_from_expr (), ctx);
   if (from == error_mark_node)
     {
       translated = error_mark_node;
@@ -2147,7 +2141,7 @@ CompileExpr::visit (HIR::RangeFromExpr &expr)
 void
 CompileExpr::visit (HIR::RangeToExpr &expr)
 {
-  tree to = CompileExpr::Compile (expr.get_to_expr ().get (), ctx);
+  tree to = CompileExpr::Compile (expr.get_to_expr (), ctx);
   if (to == error_mark_node)
     {
       translated = error_mark_node;
@@ -2182,8 +2176,8 @@ CompileExpr::visit (HIR::RangeFullExpr &expr)
 void
 CompileExpr::visit (HIR::RangeFromToInclExpr &expr)
 {
-  tree from = CompileExpr::Compile (expr.get_from_expr ().get (), ctx);
-  tree to = CompileExpr::Compile (expr.get_to_expr ().get (), ctx);
+  tree from = CompileExpr::Compile (expr.get_from_expr (), ctx);
+  tree to = CompileExpr::Compile (expr.get_to_expr (), ctx);
   if (from == error_mark_node || to == error_mark_node)
     {
       translated = error_mark_node;
@@ -2205,9 +2199,8 @@ CompileExpr::visit (HIR::RangeFromToInclExpr &expr)
 void
 CompileExpr::visit (HIR::ArrayIndexExpr &expr)
 {
-  tree array_reference
-    = CompileExpr::Compile (expr.get_array_expr ().get (), ctx);
-  tree index = CompileExpr::Compile (expr.get_index_expr ().get (), ctx);
+  tree array_reference = CompileExpr::Compile (expr.get_array_expr (), ctx);
+  tree index = CompileExpr::Compile (expr.get_index_expr (), ctx);
 
   // this might be an core::ops::index lang item situation
   TyTy::FnType *fntype;
@@ -2218,8 +2211,8 @@ CompileExpr::visit (HIR::ArrayIndexExpr &expr)
       auto lang_item_type = LangItem::Kind::INDEX;
       tree operator_overload_call
 	= resolve_operator_overload (lang_item_type, expr, array_reference,
-				     index, expr.get_array_expr ().get (),
-				     expr.get_index_expr ().get ());
+				     index, expr.get_array_expr (),
+				     expr.get_index_expr ());
 
       tree actual_type = TREE_TYPE (operator_overload_call);
       bool can_indirect = TYPE_PTR_P (actual_type) || TYPE_REF_P (actual_type);
@@ -2241,7 +2234,7 @@ CompileExpr::visit (HIR::ArrayIndexExpr &expr)
   // indirection if required
   TyTy::BaseType *array_expr_ty = nullptr;
   bool ok = ctx->get_tyctx ()->lookup_type (
-    expr.get_array_expr ()->get_mappings ().get_hirid (), &array_expr_ty);
+    expr.get_array_expr ().get_mappings ().get_hirid (), &array_expr_ty);
   rust_assert (ok);
 
   // do we need to add an indirect reference
@@ -2392,7 +2385,7 @@ CompileExpr::generate_closure_function (HIR::ClosureExpr &expr,
 	= Backend::struct_field_expression (args_param_expr, i,
 					    closure_param.get_locus ());
 
-      CompilePatternBindings::Compile (closure_param.get_pattern ().get (),
+      CompilePatternBindings::Compile (closure_param.get_pattern (),
 				       compiled_param_var, ctx);
       i++;
     }
@@ -2404,13 +2397,13 @@ CompileExpr::generate_closure_function (HIR::ClosureExpr &expr,
     }
 
   // lookup locals
-  HIR::Expr *function_body = expr.get_expr ().get ();
+  HIR::Expr &function_body = expr.get_expr ();
   bool is_block_expr
-    = function_body->get_expression_type () == HIR::Expr::ExprType::Block;
+    = function_body.get_expression_type () == HIR::Expr::ExprType::Block;
 
   if (is_block_expr)
     {
-      auto body_mappings = function_body->get_mappings ();
+      auto body_mappings = function_body.get_mappings ();
       if (flag_name_resolution_2_0)
 	{
 	  auto nr_ctx
@@ -2431,13 +2424,13 @@ CompileExpr::generate_closure_function (HIR::ClosureExpr &expr,
     }
 
   tree enclosing_scope = NULL_TREE;
-  location_t start_location = function_body->get_locus ();
-  location_t end_location = function_body->get_locus ();
+  location_t start_location = function_body.get_locus ();
+  location_t end_location = function_body.get_locus ();
   if (is_block_expr)
     {
-      HIR::BlockExpr *body = static_cast<HIR::BlockExpr *> (function_body);
-      start_location = body->get_locus ();
-      end_location = body->get_end_locus ();
+      auto &body = static_cast<HIR::BlockExpr &> (function_body);
+      start_location = body.get_locus ();
+      end_location = body.get_end_locus ();
     }
 
   tree code_block = Backend::block (fndecl, enclosing_scope, {} /*locals*/,
@@ -2462,15 +2455,14 @@ CompileExpr::generate_closure_function (HIR::ClosureExpr &expr,
 
   if (is_block_expr)
     {
-      HIR::BlockExpr *body = static_cast<HIR::BlockExpr *> (function_body);
-      compile_function_body (fndecl, *body, tyret);
+      auto &body = static_cast<HIR::BlockExpr &> (function_body);
+      compile_function_body (fndecl, body, tyret);
     }
   else
     {
       tree value = CompileExpr::Compile (function_body, ctx);
       tree return_expr
-	= Backend::return_statement (fndecl, value,
-				     function_body->get_locus ());
+	= Backend::return_statement (fndecl, value, function_body.get_locus ());
       ctx->add_statement (return_expr);
     }
 
@@ -2557,8 +2549,8 @@ CompileExpr::generate_possible_fn_trait_call (HIR::CallExpr &expr,
     }
 
   // need to apply any autoderef's to the self argument
-  HIR::Expr *fnexpr = expr.get_fnexpr ().get ();
-  HirId autoderef_mappings_id = fnexpr->get_mappings ().get_hirid ();
+  HIR::Expr &fnexpr = expr.get_fnexpr ();
+  HirId autoderef_mappings_id = fnexpr.get_mappings ().get_hirid ();
   std::vector<Resolver::Adjustment> *adjustments = nullptr;
   bool ok = ctx->get_tyctx ()->lookup_autoderef_mappings (autoderef_mappings_id,
 							  &adjustments);
@@ -2571,7 +2563,7 @@ CompileExpr::generate_possible_fn_trait_call (HIR::CallExpr &expr,
   std::vector<tree> tuple_arg_vals;
   for (auto &argument : expr.get_arguments ())
     {
-      auto rvalue = CompileExpr::Compile (argument.get (), ctx);
+      auto rvalue = CompileExpr::Compile (*argument, ctx);
       tuple_arg_vals.push_back (rvalue);
     }
 
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index 2312375ff49a..0178a93f144e 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -28,7 +28,7 @@ namespace Compile {
 class CompileExpr : private HIRCompileBase, protected HIR::HIRExpressionVisitor
 {
 public:
-  static tree Compile (HIR::Expr *expr, Context *ctx);
+  static tree Compile (HIR::Expr &expr, Context *ctx);
 
   void visit (HIR::TupleIndexExpr &expr) override;
   void visit (HIR::TupleExpr &expr) override;
@@ -98,8 +98,8 @@ protected:
 
   tree resolve_operator_overload (LangItem::Kind lang_item_type,
 				  HIR::OperatorExprMeta expr, tree lhs,
-				  tree rhs, HIR::Expr *lhs_expr,
-				  HIR::Expr *rhs_expr);
+				  tree rhs, HIR::Expr &lhs_expr,
+				  tl::optional<HIR::Expr &> rhs_expr);
 
   tree compile_bool_literal (const HIR::LiteralExpr &expr,
 			     const TyTy::BaseType *tyty);
diff --git a/gcc/rust/backend/rust-compile-fnparam.cc b/gcc/rust/backend/rust-compile-fnparam.cc
index af24ca003b9b..c00092d219e2 100644
--- a/gcc/rust/backend/rust-compile-fnparam.cc
+++ b/gcc/rust/backend/rust-compile-fnparam.cc
@@ -31,20 +31,20 @@ CompileFnParam::CompileFnParam (Context *ctx, tree fndecl, tree decl_type,
 {}
 
 Bvariable *
-CompileFnParam::compile (Context *ctx, tree fndecl, HIR::FunctionParam *param,
+CompileFnParam::compile (Context *ctx, tree fndecl, HIR::FunctionParam &param,
 			 tree decl_type, location_t locus)
 {
   CompileFnParam compiler (ctx, fndecl, decl_type, locus);
-  param->get_param_name ()->accept_vis (compiler);
+  param.get_param_name ().accept_vis (compiler);
   return compiler.compiled_param;
 }
 
 Bvariable *
-CompileFnParam::compile (Context *ctx, tree fndecl, HIR::Pattern *param,
+CompileFnParam::compile (Context *ctx, tree fndecl, HIR::Pattern &param,
 			 tree decl_type, location_t locus)
 {
   CompileFnParam compiler (ctx, fndecl, decl_type, locus);
-  param->accept_vis (compiler);
+  param.accept_vis (compiler);
   return compiler.compiled_param;
 }
 
@@ -72,21 +72,21 @@ void
 CompileFnParam::visit (HIR::StructPattern &pattern)
 {
   tree tmp_param_var = create_tmp_param_var (decl_type);
-  CompilePatternBindings::Compile (&pattern, tmp_param_var, ctx);
+  CompilePatternBindings::Compile (pattern, tmp_param_var, ctx);
 }
 
 void
 CompileFnParam::visit (HIR::TupleStructPattern &pattern)
 {
   tree tmp_param_var = create_tmp_param_var (decl_type);
-  CompilePatternBindings::Compile (&pattern, tmp_param_var, ctx);
+  CompilePatternBindings::Compile (pattern, tmp_param_var, ctx);
 }
 
 void
 CompileFnParam::visit (HIR::ReferencePattern &pattern)
 {
   tree tmp_param_var = create_tmp_param_var (decl_type);
-  CompilePatternBindings::Compile (&pattern, tmp_param_var, ctx);
+  CompilePatternBindings::Compile (pattern, tmp_param_var, ctx);
 }
 
 Bvariable *
diff --git a/gcc/rust/backend/rust-compile-fnparam.h b/gcc/rust/backend/rust-compile-fnparam.h
index 09a3e69f717d..82a705fde7b9 100644
--- a/gcc/rust/backend/rust-compile-fnparam.h
+++ b/gcc/rust/backend/rust-compile-fnparam.h
@@ -29,9 +29,9 @@ class CompileFnParam : private HIRCompileBase, protected HIR::HIRPatternVisitor
 {
 public:
   static Bvariable *compile (Context *ctx, tree fndecl,
-			     HIR::FunctionParam *param, tree decl_type,
+			     HIR::FunctionParam &param, tree decl_type,
 			     location_t locus);
-  static Bvariable *compile (Context *ctx, tree fndecl, HIR::Pattern *param,
+  static Bvariable *compile (Context *ctx, tree fndecl, HIR::Pattern &param,
 			     tree decl_type, location_t locus);
 
   void visit (HIR::IdentifierPattern &pattern) override;
diff --git a/gcc/rust/backend/rust-compile-implitem.cc b/gcc/rust/backend/rust-compile-implitem.cc
index 98337c8f9bb4..352685e242f8 100644
--- a/gcc/rust/backend/rust-compile-implitem.cc
+++ b/gcc/rust/backend/rust-compile-implitem.cc
@@ -44,7 +44,7 @@ CompileTraitItem::visit (HIR::TraitItemConst &constant)
 
   rust_assert (canonical_path);
 
-  HIR::Expr *const_value_expr = constant.get_expr ().get ();
+  HIR::Expr &const_value_expr = constant.get_expr ();
   tree const_expr
     = compile_constant_item (resolved_type, *canonical_path, const_value_expr,
 			     constant.get_locus ());
@@ -114,7 +114,7 @@ CompileTraitItem::visit (HIR::TraitItemFunc &func)
 			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);
+			&func.get_block_expr (), *canonical_path, fntype);
   reference = address_expression (fndecl, ref_locus);
 }
 
diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc
index de3bb6e32031..bf595e4fb871 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -321,7 +321,7 @@ compile_fn_params (Context *ctx, TyTy::FnType *fntype, tree fndecl,
 
       location_t param_locus = referenced_param->get_locus ();
       Bvariable *compiled_param_var
-	= CompileFnParam::compile (ctx, fndecl, referenced_param,
+	= CompileFnParam::compile (ctx, fndecl, *referenced_param,
 				   compiled_param_type, param_locus);
 
       compiled_param_variables->push_back (compiled_param_var);
diff --git a/gcc/rust/backend/rust-compile-item.cc b/gcc/rust/backend/rust-compile-item.cc
index 08787163c2a5..dd37e3997d69 100644
--- a/gcc/rust/backend/rust-compile-item.cc
+++ b/gcc/rust/backend/rust-compile-item.cc
@@ -60,7 +60,7 @@ CompileItem::visit (HIR::StaticItem &var)
 
   rust_assert (canonical_path.has_value ());
 
-  HIR::Expr *const_value_expr = var.get_expr ().get ();
+  HIR::Expr &const_value_expr = var.get_expr ();
   ctx->push_const_context ();
   tree value = compile_constant_item (resolved_type, *canonical_path,
 				      const_value_expr, var.get_locus ());
@@ -120,7 +120,7 @@ CompileItem::visit (HIR::ConstantItem &constant)
 			 .value ();
     }
 
-  HIR::Expr *const_value_expr = constant.get_expr ().get ();
+  HIR::Expr &const_value_expr = constant.get_expr ();
   ctx->push_const_context ();
   tree const_expr
     = compile_constant_item (resolved_type, canonical_path, const_value_expr,
@@ -222,8 +222,7 @@ CompileItem::visit (HIR::Function &function)
 			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.get_definition (), canonical_path, fntype);
   reference = address_expression (fndecl, ref_locus);
 
   if (function.get_qualifiers ().is_const ())
@@ -235,7 +234,7 @@ 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))
+	impl_block.get_type ().get_mappings ().get_hirid (), &self_lookup))
     {
       rust_error_at (impl_block.get_locus (), "failed to resolve type of impl");
       return;
diff --git a/gcc/rust/backend/rust-compile-pattern.cc b/gcc/rust/backend/rust-compile-pattern.cc
index ffa1fa7f5dc1..d6161bd5e831 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -67,7 +67,7 @@ CompilePatternCheckExpr::visit (HIR::PathInExpression &pattern)
   // must be enum
   match_scrutinee_expr = scrutinee_expr_qualifier_expr;
 
-  HIR::Expr *discrim_expr = variant->get_discriminant ();
+  HIR::Expr &discrim_expr = variant->get_discriminant ();
   tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
 
   check_expr
@@ -80,10 +80,9 @@ void
 CompilePatternCheckExpr::visit (HIR::LiteralPattern &pattern)
 {
   // Compile the literal
-  HIR::LiteralExpr *litexpr
-    = new HIR::LiteralExpr (pattern.get_mappings (), pattern.get_literal (),
-			    pattern.get_locus (),
-			    std::vector<AST::Attribute> ());
+  auto litexpr = Rust::make_unique<HIR::LiteralExpr> (
+    HIR::LiteralExpr (pattern.get_mappings (), pattern.get_literal (),
+		      pattern.get_locus (), std::vector<AST::Attribute> ()));
 
   // Note: Floating point literals are currently accepted but will likely be
   // forbidden in LiteralPatterns in a future version of Rust.
@@ -95,7 +94,7 @@ CompilePatternCheckExpr::visit (HIR::LiteralPattern &pattern)
       rust_sorry_at (pattern.get_locus (), "floating-point literal in pattern");
     }
 
-  tree lit = CompileExpr::Compile (litexpr, ctx);
+  tree lit = CompileExpr::Compile (*litexpr, ctx);
 
   check_expr = Backend::comparison_expression (ComparisonOperator::EQUAL,
 					       match_scrutinee_expr, lit,
@@ -103,19 +102,17 @@ CompilePatternCheckExpr::visit (HIR::LiteralPattern &pattern)
 }
 
 static tree
-compile_range_pattern_bound (HIR::RangePatternBound *bound,
+compile_range_pattern_bound (HIR::RangePatternBound &bound,
 			     Analysis::NodeMapping mappings, location_t locus,
 			     Context *ctx)
 {
   tree result = NULL_TREE;
-  switch (bound->get_bound_type ())
+  switch (bound.get_bound_type ())
     {
       case HIR::RangePatternBound::RangePatternBoundType::LITERAL: {
-	HIR::RangePatternBoundLiteral &ref
-	  = *static_cast<HIR::RangePatternBoundLiteral *> (bound);
+	auto &ref = static_cast<HIR::RangePatternBoundLiteral &> (bound);
 
-	HIR::LiteralExpr *litexpr
-	  = new HIR::LiteralExpr (mappings, ref.get_literal (), locus,
+	HIR::LiteralExpr litexpr (mappings, ref.get_literal (), locus,
 				  std::vector<AST::Attribute> ());
 
 	result = CompileExpr::Compile (litexpr, ctx);
@@ -123,8 +120,7 @@ compile_range_pattern_bound (HIR::RangePatternBound *bound,
       break;
 
       case HIR::RangePatternBound::RangePatternBoundType::PATH: {
-	HIR::RangePatternBoundPath &ref
-	  = *static_cast<HIR::RangePatternBoundPath *> (bound);
+	auto &ref = static_cast<HIR::RangePatternBoundPath &> (bound);
 
 	result = ResolvePathRef::Compile (ref.get_path (), ctx);
 
@@ -134,8 +130,7 @@ compile_range_pattern_bound (HIR::RangePatternBound *bound,
       break;
 
       case HIR::RangePatternBound::RangePatternBoundType::QUALPATH: {
-	HIR::RangePatternBoundQualPath &ref
-	  = *static_cast<HIR::RangePatternBoundQualPath *> (bound);
+	auto &ref = static_cast<HIR::RangePatternBoundQualPath &> (bound);
 
 	result = ResolvePathRef::Compile (ref.get_qualified_path (), ctx);
 
@@ -150,10 +145,10 @@ compile_range_pattern_bound (HIR::RangePatternBound *bound,
 void
 CompilePatternCheckExpr::visit (HIR::RangePattern &pattern)
 {
-  tree upper = compile_range_pattern_bound (pattern.get_upper_bound ().get (),
+  tree upper = compile_range_pattern_bound (pattern.get_upper_bound (),
 					    pattern.get_mappings (),
 					    pattern.get_locus (), ctx);
-  tree lower = compile_range_pattern_bound (pattern.get_lower_bound ().get (),
+  tree lower = compile_range_pattern_bound (pattern.get_lower_bound (),
 					    pattern.get_mappings (),
 					    pattern.get_locus (), ctx);
 
@@ -175,7 +170,7 @@ CompilePatternCheckExpr::visit (HIR::ReferencePattern &pattern)
 {
   match_scrutinee_expr
     = indirect_expression (match_scrutinee_expr, pattern.get_locus ());
-  pattern.get_referenced_pattern ()->accept_vis (*this);
+  pattern.get_referenced_pattern ().accept_vis (*this);
 }
 
 void
@@ -183,14 +178,13 @@ CompilePatternCheckExpr::visit (HIR::AltPattern &pattern)
 {
   auto &alts = pattern.get_alts ();
 
-  check_expr = CompilePatternCheckExpr::Compile (alts.at (0).get (),
+  check_expr = CompilePatternCheckExpr::Compile (*alts.at (0),
 						 match_scrutinee_expr, ctx);
   auto end = alts.end ();
   for (auto i = alts.begin () + 1; i != end; i++)
     {
       tree next_expr
-	= CompilePatternCheckExpr::Compile (i->get (), match_scrutinee_expr,
-					    ctx);
+	= CompilePatternCheckExpr::Compile (**i, match_scrutinee_expr, ctx);
       check_expr = Backend::arithmetic_or_logical_expression (
 	ArithmeticOrLogicalOperator::BITWISE_OR, check_expr, next_expr,
 	(*i)->get_locus ());
@@ -229,7 +223,7 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern)
       // // would be DECL_QUALIFIER i think. For now this will just access the
       // // first record field and its respective qualifier because it will
       // // always be set because this is all a big special union
-      HIR::Expr *discrim_expr = variant->get_discriminant ();
+      HIR::Expr &discrim_expr = variant->get_discriminant ();
       tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
 
       // find discriminant field of scrutinee
@@ -282,11 +276,11 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern)
 						  ident.get_locus ());
 
 	    tree check_expr_sub
-	      = CompilePatternCheckExpr::Compile (ident.get_pattern ().get (),
+	      = CompilePatternCheckExpr::Compile (ident.get_pattern (),
 						  field_expr, ctx);
 	    check_expr = Backend::arithmetic_or_logical_expression (
 	      ArithmeticOrLogicalOperator::BITWISE_AND, check_expr,
-	      check_expr_sub, ident.get_pattern ()->get_locus ());
+	      check_expr_sub, ident.get_pattern ().get_locus ());
 	  }
 	  break;
 
@@ -328,7 +322,7 @@ CompilePatternCheckExpr::visit (HIR::TupleStructPattern &pattern)
       rust_assert (ok);
 
       // find expected discriminant
-      HIR::Expr *discrim_expr = variant->get_discriminant ();
+      HIR::Expr &discrim_expr = variant->get_discriminant ();
       tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
 
       // find discriminant field of scrutinee
@@ -357,8 +351,8 @@ CompilePatternCheckExpr::visit (HIR::TupleStructPattern &pattern)
       tuple_field_index = 0;
     }
 
-  std::unique_ptr<HIR::TupleStructItems> &items = pattern.get_items ();
-  switch (items->get_item_type ())
+  HIR::TupleStructItems &items = pattern.get_items ();
+  switch (items.get_item_type ())
     {
       case HIR::TupleStructItems::RANGED: {
 	// TODO
@@ -368,7 +362,7 @@ CompilePatternCheckExpr::visit (HIR::TupleStructPattern &pattern)
 
       case HIR::TupleStructItems::MULTIPLE: {
 	HIR::TupleStructItemsNoRange &items_no_range
-	  = static_cast<HIR::TupleStructItemsNoRange &> (*items.get ());
+	  = static_cast<HIR::TupleStructItemsNoRange &> (items);
 
 	rust_assert (items_no_range.get_patterns ().size ()
 		     == variant->num_fields ());
@@ -381,8 +375,7 @@ CompilePatternCheckExpr::visit (HIR::TupleStructPattern &pattern)
 						  pattern->get_locus ());
 
 	    tree check_expr_sub
-	      = CompilePatternCheckExpr::Compile (pattern.get (), field_expr,
-						  ctx);
+	      = CompilePatternCheckExpr::Compile (*pattern, field_expr, ctx);
 	    check_expr = Backend::arithmetic_or_logical_expression (
 	      ArithmeticOrLogicalOperator::BITWISE_AND, check_expr,
 	      check_expr_sub, pattern->get_locus ());
@@ -397,7 +390,7 @@ CompilePatternCheckExpr::visit (HIR::TuplePattern &pattern)
 {
   check_expr = boolean_true_node;
 
-  switch (pattern.get_items ()->get_item_type ())
+  switch (pattern.get_items ().get_item_type ())
     {
       case HIR::TuplePatternItems::RANGED: {
 	// TODO
@@ -407,7 +400,7 @@ CompilePatternCheckExpr::visit (HIR::TuplePattern &pattern)
 
       case HIR::TuplePatternItems::MULTIPLE: {
 	auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
-	  *pattern.get_items ());
+	  pattern.get_items ());
 	size_t tuple_field_index = 0;
 
 	for (auto &pat : items.get_patterns ())
@@ -418,7 +411,7 @@ CompilePatternCheckExpr::visit (HIR::TuplePattern &pattern)
 						  pat->get_locus ());
 
 	    tree check_expr_sub
-	      = CompilePatternCheckExpr::Compile (pat.get (), field_expr, ctx);
+	      = CompilePatternCheckExpr::Compile (*pat, field_expr, ctx);
 	    check_expr = Backend::arithmetic_or_logical_expression (
 	      ArithmeticOrLogicalOperator::BITWISE_AND, check_expr,
 	      check_expr_sub, pat->get_locus ());
@@ -459,8 +452,8 @@ CompilePatternBindings::visit (HIR::TupleStructPattern &pattern)
   rust_assert (variant->get_variant_type ()
 	       == TyTy::VariantDef::VariantType::TUPLE);
 
-  std::unique_ptr<HIR::TupleStructItems> &items = pattern.get_items ();
-  switch (items->get_item_type ())
+  HIR::TupleStructItems &items = pattern.get_items ();
+  switch (items.get_item_type ())
     {
       case HIR::TupleStructItems::RANGED: {
 	// TODO
@@ -470,7 +463,7 @@ CompilePatternBindings::visit (HIR::TupleStructPattern &pattern)
 
       case HIR::TupleStructItems::MULTIPLE: {
 	HIR::TupleStructItemsNoRange &items_no_range
-	  = static_cast<HIR::TupleStructItemsNoRange &> (*items.get ());
+	  = static_cast<HIR::TupleStructItemsNoRange &> (items);
 
 	rust_assert (items_no_range.get_patterns ().size ()
 		     == variant->num_fields ());
@@ -609,8 +602,8 @@ CompilePatternBindings::visit (HIR::ReferencePattern &pattern)
   tree derefed
     = indirect_expression (match_scrutinee_expr, pattern.get_locus ());
 
-  CompilePatternBindings::Compile (pattern.get_referenced_pattern ().get (),
-				   derefed, ctx);
+  CompilePatternBindings::Compile (pattern.get_referenced_pattern (), derefed,
+				   ctx);
 }
 
 void
@@ -670,12 +663,12 @@ CompilePatternLet::visit (HIR::TuplePattern &pattern)
   tree access_expr = Backend::var_expression (tmp_var, pattern.get_locus ());
   ctx->add_statement (init_stmt);
 
-  switch (pattern.get_items ()->get_item_type ())
+  switch (pattern.get_items ().get_item_type ())
     {
       case HIR::TuplePatternItems::ItemType::RANGED: {
 	size_t tuple_idx = 0;
 	auto &items
-	  = static_cast<HIR::TuplePatternItemsRanged &> (*pattern.get_items ());
+	  = static_cast<HIR::TuplePatternItemsRanged &> (pattern.get_items ());
 
 	auto &items_lower = items.get_lower_patterns ();
 	auto &items_upper = items.get_upper_patterns ();
@@ -719,7 +712,7 @@ CompilePatternLet::visit (HIR::TuplePattern &pattern)
       case HIR::TuplePatternItems::ItemType::MULTIPLE: {
 	size_t tuple_idx = 0;
 	auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
-	  *pattern.get_items ());
+	  pattern.get_items ());
 
 	for (auto &sub : items.get_patterns ())
 	  {
diff --git a/gcc/rust/backend/rust-compile-pattern.h b/gcc/rust/backend/rust-compile-pattern.h
index 521ed0d6e921..0b785c6ce8c9 100644
--- a/gcc/rust/backend/rust-compile-pattern.h
+++ b/gcc/rust/backend/rust-compile-pattern.h
@@ -26,11 +26,11 @@ class CompilePatternCheckExpr : public HIRCompileBase,
 				public HIR::HIRPatternVisitor
 {
 public:
-  static tree Compile (HIR::Pattern *pattern, tree match_scrutinee_expr,
+  static tree Compile (HIR::Pattern &pattern, tree match_scrutinee_expr,
 		       Context *ctx)
   {
     CompilePatternCheckExpr compiler (ctx, match_scrutinee_expr);
-    pattern->accept_vis (compiler);
+    pattern.accept_vis (compiler);
     rust_assert (compiler.check_expr);
     return compiler.check_expr;
   }
@@ -71,11 +71,11 @@ class CompilePatternBindings : public HIRCompileBase,
 			       public HIR::HIRPatternVisitor
 {
 public:
-  static void Compile (HIR::Pattern *pattern, tree match_scrutinee_expr,
+  static void Compile (HIR::Pattern &pattern, tree match_scrutinee_expr,
 		       Context *ctx)
   {
     CompilePatternBindings compiler (ctx, match_scrutinee_expr);
-    pattern->accept_vis (compiler);
+    pattern.accept_vis (compiler);
   }
 
   void visit (HIR::StructPattern &pattern) override;
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc
index 7c9b303b8519..31ebbf14b74e 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -81,7 +81,7 @@ ResolvePathRef::attempt_constructor_expression_lookup (
   tree compiled_adt_type = TyTyResolveCompile::compile (ctx, adt);
 
   // make the ctor for the union
-  HIR::Expr *discrim_expr = variant->get_discriminant ();
+  HIR::Expr &discrim_expr = variant->get_discriminant ();
   tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
   tree folded_discrim_expr = fold_expr (discrim_expr_node);
   tree qualifier = folded_discrim_expr;
@@ -301,7 +301,7 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup,
 
 	      TyTy::BaseType *self = nullptr;
 	      bool ok = ctx->get_tyctx ()->lookup_type (
-		impl->get_type ()->get_mappings ().get_hirid (), &self);
+		impl->get_type ().get_mappings ().get_hirid (), &self);
 	      rust_assert (ok);
 
 	      if (!lookup->has_substitutions_defined ())
diff --git a/gcc/rust/backend/rust-compile-stmt.cc b/gcc/rust/backend/rust-compile-stmt.cc
index d8b27ffb18c6..a4b5a989fc47 100644
--- a/gcc/rust/backend/rust-compile-stmt.cc
+++ b/gcc/rust/backend/rust-compile-stmt.cc
@@ -40,13 +40,13 @@ CompileStmt::Compile (HIR::Stmt *stmt, Context *ctx)
 void
 CompileStmt::visit (HIR::ExprStmt &stmt)
 {
-  translated = CompileExpr::Compile (stmt.get_expr ().get (), ctx);
+  translated = CompileExpr::Compile (stmt.get_expr (), ctx);
 }
 
 void
 CompileStmt::visit (HIR::LetStmt &stmt)
 {
-  HIR::Pattern &stmt_pattern = *stmt.get_pattern ();
+  HIR::Pattern &stmt_pattern = stmt.get_pattern ();
   HirId stmt_id = stmt_pattern.get_mappings ().get_hirid ();
 
   TyTy::BaseType *ty = nullptr;
@@ -68,7 +68,7 @@ CompileStmt::visit (HIR::LetStmt &stmt)
   if (!stmt.has_init_expr ())
     return;
 
-  tree init = CompileExpr::Compile (stmt.get_init_expr ().get (), ctx);
+  tree init = CompileExpr::Compile (stmt.get_init_expr (), ctx);
   // FIXME use error_mark_node, check that CompileExpr returns error_mark_node
   // on failure and make this an assertion
   if (init == nullptr)
@@ -76,11 +76,11 @@ CompileStmt::visit (HIR::LetStmt &stmt)
 
   TyTy::BaseType *actual = nullptr;
   bool ok = ctx->get_tyctx ()->lookup_type (
-    stmt.get_init_expr ()->get_mappings ().get_hirid (), &actual);
+    stmt.get_init_expr ().get_mappings ().get_hirid (), &actual);
   rust_assert (ok);
 
-  location_t lvalue_locus = stmt.get_pattern ()->get_locus ();
-  location_t rvalue_locus = stmt.get_init_expr ()->get_locus ();
+  location_t lvalue_locus = stmt.get_pattern ().get_locus ();
+  location_t rvalue_locus = stmt.get_init_expr ().get_locus ();
   TyTy::BaseType *expected = ty;
   init = coercion_site (stmt.get_mappings ().get_hirid (), init, actual,
 			expected, lvalue_locus, rvalue_locus);
diff --git a/gcc/rust/backend/rust-compile-struct-field-expr.cc b/gcc/rust/backend/rust-compile-struct-field-expr.cc
index 4a3b26c22e2a..0ac25e7a822a 100644
--- a/gcc/rust/backend/rust-compile-struct-field-expr.cc
+++ b/gcc/rust/backend/rust-compile-struct-field-expr.cc
@@ -27,22 +27,22 @@ CompileStructExprField::CompileStructExprField (Context *ctx)
 {}
 
 tree
-CompileStructExprField::Compile (HIR::StructExprField *field, Context *ctx)
+CompileStructExprField::Compile (HIR::StructExprField &field, Context *ctx)
 {
   CompileStructExprField compiler (ctx);
-  switch (field->get_kind ())
+  switch (field.get_kind ())
     {
     case HIR::StructExprField::StructExprFieldKind::IDENTIFIER:
-      compiler.visit (static_cast<HIR::StructExprFieldIdentifier &> (*field));
+      compiler.visit (static_cast<HIR::StructExprFieldIdentifier &> (field));
       break;
 
     case HIR::StructExprField::StructExprFieldKind::IDENTIFIER_VALUE:
       compiler.visit (
-	static_cast<HIR::StructExprFieldIdentifierValue &> (*field));
+	static_cast<HIR::StructExprFieldIdentifierValue &> (field));
       break;
 
     case HIR::StructExprField::StructExprFieldKind::INDEX_VALUE:
-      compiler.visit (static_cast<HIR::StructExprFieldIndexValue &> (*field));
+      compiler.visit (static_cast<HIR::StructExprFieldIndexValue &> (field));
       break;
     }
   return compiler.translated;
@@ -51,13 +51,13 @@ CompileStructExprField::Compile (HIR::StructExprField *field, Context *ctx)
 void
 CompileStructExprField::visit (HIR::StructExprFieldIdentifierValue &field)
 {
-  translated = CompileExpr::Compile (field.get_value ().get (), ctx);
+  translated = CompileExpr::Compile (field.get_value (), ctx);
 }
 
 void
 CompileStructExprField::visit (HIR::StructExprFieldIndexValue &field)
 {
-  translated = CompileExpr::Compile (field.get_value ().get (), ctx);
+  translated = CompileExpr::Compile (field.get_value (), ctx);
 }
 
 void
@@ -74,7 +74,7 @@ CompileStructExprField::visit (HIR::StructExprFieldIdentifier &field)
 			    HIR::GenericArgs::create_empty ());
   HIR::PathInExpression expr (mappings_copy2, {seg}, field.get_locus (), false,
 			      {});
-  translated = CompileExpr::Compile (&expr, ctx);
+  translated = CompileExpr::Compile (expr, ctx);
 }
 
 } // namespace Compile
diff --git a/gcc/rust/backend/rust-compile-struct-field-expr.h b/gcc/rust/backend/rust-compile-struct-field-expr.h
index f1d70552a084..055019cf1eb5 100644
--- a/gcc/rust/backend/rust-compile-struct-field-expr.h
+++ b/gcc/rust/backend/rust-compile-struct-field-expr.h
@@ -27,7 +27,7 @@ namespace Compile {
 class CompileStructExprField : private HIRCompileBase
 {
 public:
-  static tree Compile (HIR::StructExprField *field, Context *ctx);
+  static tree Compile (HIR::StructExprField &field, Context *ctx);
 
 protected:
   void visit (HIR::StructExprFieldIdentifierValue &field);
diff --git a/gcc/rust/backend/rust-compile-type.cc b/gcc/rust/backend/rust-compile-type.cc
index b546a05f6a8e..c53b359b01fc 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::ArrayType &type)
     = TyTyResolveCompile::compile (ctx, type.get_element_type ());
 
   ctx->push_const_context ();
-  tree capacity_expr = CompileExpr::Compile (&type.get_capacity_expr (), ctx);
+  tree capacity_expr = CompileExpr::Compile (type.get_capacity_expr (), ctx);
   ctx->pop_const_context ();
 
   tree folded_capacity_expr = fold_expr (capacity_expr);
diff --git a/gcc/rust/backend/rust-compile-var-decl.h b/gcc/rust/backend/rust-compile-var-decl.h
index 6b6af77a958b..4c46a7b17d6d 100644
--- a/gcc/rust/backend/rust-compile-var-decl.h
+++ b/gcc/rust/backend/rust-compile-var-decl.h
@@ -68,12 +68,12 @@ public:
 
   void visit (HIR::TuplePattern &pattern) override
   {
-    switch (pattern.get_items ()->get_item_type ())
+    switch (pattern.get_items ().get_item_type ())
       {
 	case HIR::TuplePatternItems::ItemType::MULTIPLE: {
 	  rust_assert (TREE_CODE (translated_type) == RECORD_TYPE);
 	  auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
-	    *pattern.get_items ());
+	    pattern.get_items ());
 
 	  size_t offs = 0;
 	  for (auto &sub : items.get_patterns ())
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index 7e0a9b6920f7..7b000662c8d2 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -259,17 +259,17 @@ HIRCompileBase::compute_address_for_trait_item (
       HIR::ImplBlock *impl_block = item.second;
       rust_assert (impl_block != nullptr);
 
-      // Lookup type for potentially associated impl.
-      std::unique_ptr<HIR::Type> &self_type_path = impl_block->get_type ();
-
       // Checks for empty impl blocks, triggered by Sized trait.
-      if (self_type_path == nullptr)
+      if (!impl_block->has_type ())
 	continue;
 
+      // Lookup type for potentially associated impl.
+      HIR::Type &self_type_path = impl_block->get_type ();
+
       // Convert HIR::Type to TyTy::BaseType
       TyTy::BaseType *self = nullptr;
       bool ok = ctx->get_tyctx ()->lookup_type (
-	self_type_path->get_mappings ().get_hirid (), &self);
+	self_type_path.get_mappings ().get_hirid (), &self);
 
       rust_assert (ok);
 
diff --git a/gcc/rust/backend/rust-mangle-v0.cc b/gcc/rust/backend/rust-mangle-v0.cc
index d604dcf725cd..67d7e4d1885a 100644
--- a/gcc/rust/backend/rust-mangle-v0.cc
+++ b/gcc/rust/backend/rust-mangle-v0.cc
@@ -328,7 +328,7 @@ v0_inherent_or_trait_impl_path (Rust::Compile::Context *ctx,
   // lookup impl type
   TyTy::BaseType *impl_ty = nullptr;
   ok = ctx->get_tyctx ()->lookup_type (
-    impl_block->get_type ()->get_mappings ().get_hirid (), &impl_ty);
+    impl_block->get_type ().get_mappings ().get_hirid (), &impl_ty);
   rust_assert (ok);
 
   // FIXME: dummy value for now
@@ -342,7 +342,7 @@ v0_inherent_or_trait_impl_path (Rust::Compile::Context *ctx,
 
       TyTy::BaseType *trait_ty = nullptr;
       ok = ctx->get_tyctx ()->lookup_type (
-	impl_block->get_trait_ref ()->get_mappings ().get_hirid (), &trait_ty);
+	impl_block->get_trait_ref ().get_mappings ().get_hirid (), &trait_ty);
       rust_assert (ok);
 
       v0path.trait_type = v0_type_prefix (ctx, trait_ty);
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
index df02c4b5e61b..d6acc6abcefe 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
@@ -135,7 +135,7 @@ ExprStmtBuilder::visit (HIR::LiteralExpr &expr)
 void
 ExprStmtBuilder::visit (HIR::BorrowExpr &expr)
 {
-  auto operand = visit_expr (*expr.get_expr ());
+  auto operand = visit_expr (expr.get_expr ());
   if (ctx.place_db[operand].is_constant ())
     {
       // Cannot borrow a constant, must create a temporary copy.
@@ -150,7 +150,7 @@ ExprStmtBuilder::visit (HIR::BorrowExpr &expr)
 void
 ExprStmtBuilder::visit (HIR::DereferenceExpr &expr)
 {
-  auto operand = visit_expr (*expr.get_expr ());
+  auto operand = visit_expr (expr.get_expr ());
   return_place (ctx.place_db.lookup_or_add_path (Place::DEREF,
 						 lookup_type (expr), operand),
 		expr.get_locus ());
@@ -166,30 +166,31 @@ ExprStmtBuilder::visit (HIR::ErrorPropagationExpr &expr)
 void
 ExprStmtBuilder::visit (HIR::NegationExpr &expr)
 {
-  PlaceId operand = visit_expr (*expr.get_expr ());
-  return_expr (new Operator<1> ({move_place (operand, expr.get_locus ())}),
+  PlaceId operand = visit_expr (expr.get_expr ());
+  return_expr (new Operator<1> (
+		 {move_place (operand, expr.get_expr ().get_locus ())}),
 	       lookup_type (expr), expr.get_locus ());
 }
 
 void
 ExprStmtBuilder::visit (HIR::ArithmeticOrLogicalExpr &expr)
 {
-  PlaceId lhs = visit_expr (*expr.get_lhs ());
-  PlaceId rhs = visit_expr (*expr.get_rhs ());
+  PlaceId lhs = visit_expr (expr.get_lhs ());
+  PlaceId rhs = visit_expr (expr.get_rhs ());
   return_expr (new Operator<2> (
-		 {move_place (lhs, expr.get_lhs ()->get_locus ()),
-		  move_place (rhs, expr.get_rhs ()->get_locus ())}),
+		 {move_place (lhs, expr.get_lhs ().get_locus ()),
+		  move_place (rhs, expr.get_rhs ().get_locus ())}),
 	       lookup_type (expr), expr.get_locus ());
 }
 
 void
 ExprStmtBuilder::visit (HIR::ComparisonExpr &expr)
 {
-  PlaceId lhs = visit_expr (*expr.get_lhs ());
-  PlaceId rhs = visit_expr (*expr.get_rhs ());
+  PlaceId lhs = visit_expr (expr.get_lhs ());
+  PlaceId rhs = visit_expr (expr.get_rhs ());
   return_expr (new Operator<2> (
-		 {move_place (lhs, expr.get_lhs ()->get_locus ()),
-		  move_place (rhs, expr.get_rhs ()->get_locus ())}),
+		 {move_place (lhs, expr.get_lhs ().get_locus ()),
+		  move_place (rhs, expr.get_rhs ().get_locus ())}),
 	       lookup_type (expr), expr.get_locus ());
 }
 
@@ -205,7 +206,7 @@ ExprStmtBuilder::visit (HIR::LazyBooleanExpr &expr)
 void
 ExprStmtBuilder::visit (HIR::TypeCastExpr &expr)
 {
-  auto operand = visit_expr (*expr.get_expr ());
+  auto operand = visit_expr (expr.get_expr ());
   return_expr (new Operator<1> ({operand}), lookup_type (expr),
 	       expr.get_locus ());
 }
@@ -213,8 +214,8 @@ ExprStmtBuilder::visit (HIR::TypeCastExpr &expr)
 void
 ExprStmtBuilder::visit (HIR::AssignmentExpr &expr)
 {
-  auto lhs = visit_expr (*expr.get_lhs ());
-  auto rhs = visit_expr (*expr.get_rhs ());
+  auto lhs = visit_expr (expr.get_lhs ());
+  auto rhs = visit_expr (expr.get_rhs ());
   push_assignment (lhs, rhs, expr.get_locus ());
   translated = INVALID_PLACE;
 }
@@ -222,25 +223,25 @@ ExprStmtBuilder::visit (HIR::AssignmentExpr &expr)
 void
 ExprStmtBuilder::visit (HIR::CompoundAssignmentExpr &expr)
 {
-  auto lhs = visit_expr (*expr.get_lhs ());
-  auto rhs = visit_expr (*expr.get_rhs ());
+  auto lhs = visit_expr (expr.get_lhs ());
+  auto rhs = visit_expr (expr.get_rhs ());
   push_assignment (lhs, new Operator<2> ({lhs, rhs}), expr.get_locus ());
 }
 
 void
 ExprStmtBuilder::visit (HIR::GroupedExpr &expr)
 {
-  return_place (visit_expr (*expr.get_expr_in_parens ()), expr.get_locus ());
+  return_place (visit_expr (expr.get_expr_in_parens ()), expr.get_locus ());
 }
 
 void
 ExprStmtBuilder::visit (HIR::ArrayExpr &expr)
 {
   auto &elems = expr.get_internal_elements ();
-  switch (elems->get_array_expr_type ())
+  switch (elems.get_array_expr_type ())
     {
       case HIR::ArrayElems::VALUES: {
-	auto &elem_vals = (static_cast<HIR::ArrayElemsValues &> (*elems));
+	auto &elem_vals = (static_cast<HIR::ArrayElemsValues &> (elems));
 	auto init_values = visit_list (elem_vals.get_values ());
 	// collect locations
 	std::vector<location_t> value_locations;
@@ -254,8 +255,8 @@ ExprStmtBuilder::visit (HIR::ArrayExpr &expr)
 	break;
       }
       case HIR::ArrayElems::COPIED: {
-	auto &elem_copied = (static_cast<HIR::ArrayElemsCopied &> (*elems));
-	auto init = visit_expr (*elem_copied.get_elem_to_copy ());
+	auto &elem_copied = (static_cast<HIR::ArrayElemsCopied &> (elems));
+	auto init = visit_expr (elem_copied.get_elem_to_copy ());
 	return_expr (new InitializerExpr ({init}), lookup_type (expr),
 		     expr.get_locus ());
 	break;
@@ -266,8 +267,8 @@ ExprStmtBuilder::visit (HIR::ArrayExpr &expr)
 void
 ExprStmtBuilder::visit (HIR::ArrayIndexExpr &expr)
 {
-  auto lhs = visit_expr (*expr.get_array_expr ());
-  auto rhs = visit_expr (*expr.get_index_expr ());
+  auto lhs = visit_expr (expr.get_array_expr ());
+  auto rhs = visit_expr (expr.get_index_expr ());
   // The index is not tracked in BIR.
   std::ignore = rhs;
   return_place (ctx.place_db.lookup_or_add_path (Place::INDEX,
@@ -286,7 +287,7 @@ ExprStmtBuilder::visit (HIR::TupleExpr &expr)
 void
 ExprStmtBuilder::visit (HIR::TupleIndexExpr &expr)
 {
-  auto tuple = visit_expr (*expr.get_tuple_expr ());
+  auto tuple = visit_expr (expr.get_tuple_expr ());
   return_place (ctx.place_db.lookup_or_add_path (Place::FIELD,
 						 lookup_type (expr), tuple,
 						 expr.get_tuple_index ()),
@@ -296,7 +297,7 @@ ExprStmtBuilder::visit (HIR::TupleIndexExpr &expr)
 void
 ExprStmtBuilder::visit (HIR::CallExpr &expr)
 {
-  PlaceId fn = visit_expr (*expr.get_fnexpr ());
+  PlaceId fn = visit_expr (expr.get_fnexpr ());
   std::vector<PlaceId> arguments = visit_list (expr.get_arguments ());
 
   const auto fn_type
@@ -330,7 +331,7 @@ ExprStmtBuilder::visit (HIR::MethodCallExpr &expr)
 void
 ExprStmtBuilder::visit (HIR::FieldAccessExpr &expr)
 {
-  auto receiver = visit_expr (*expr.get_receiver_expr ());
+  auto receiver = visit_expr (expr.get_receiver_expr ());
   auto type = autoderef (receiver);
   rust_assert (type->get_kind () == TyTy::ADT);
   auto adt = type->as<TyTy::ADTType> ();
@@ -383,7 +384,7 @@ ExprStmtBuilder::visit (HIR::BlockExpr &block)
       if (block.has_expr () && !unreachable)
 	{
 	  push_assignment (block_ctx.label_var,
-			   visit_expr (*block.get_final_expr ()),
+			   visit_expr (block.get_final_expr ()),
 			   block.get_start_locus ());
 	}
       if (!ctx.get_current_bb ().is_terminated ())
@@ -397,9 +398,9 @@ ExprStmtBuilder::visit (HIR::BlockExpr &block)
     }
   else if (block.has_expr () && !unreachable)
     {
-      return_place (visit_expr (*block.get_final_expr (),
+      return_place (visit_expr (block.get_final_expr (),
 				take_or_create_return_place (
-				  lookup_type (*block.get_final_expr ()))),
+				  lookup_type (block.get_final_expr ()))),
 		    block.get_start_locus ());
     }
 
@@ -426,7 +427,7 @@ ExprStmtBuilder::visit (HIR::BreakExpr &brk)
   LoopAndLabelCtx info = brk.has_label () ? get_label_ctx (brk.get_label ())
 					  : get_unnamed_loop_ctx ();
   if (brk.has_break_expr ())
-    push_assignment (info.label_var, visit_expr (*brk.get_expr ()),
+    push_assignment (info.label_var, visit_expr (brk.get_expr ()),
 		     brk.get_locus ());
 
   start_new_consecutive_bb ();
@@ -438,8 +439,8 @@ ExprStmtBuilder::visit (HIR::BreakExpr &brk)
 void
 ExprStmtBuilder::visit (HIR::RangeFromToExpr &range)
 {
-  auto from = visit_expr (*range.get_from_expr ());
-  auto to = visit_expr (*range.get_to_expr ());
+  auto from = visit_expr (range.get_from_expr ());
+  auto to = visit_expr (range.get_to_expr ());
   return_expr (new InitializerExpr ({from, to}), lookup_type (range),
 	       range.get_locus ());
 }
@@ -447,7 +448,7 @@ ExprStmtBuilder::visit (HIR::RangeFromToExpr &range)
 void
 ExprStmtBuilder::visit (HIR::RangeFromExpr &expr)
 {
-  auto from = visit_expr (*expr.get_from_expr ());
+  auto from = visit_expr (expr.get_from_expr ());
   return_expr (new InitializerExpr ({from}), lookup_type (expr),
 	       expr.get_locus ());
 }
@@ -455,7 +456,7 @@ ExprStmtBuilder::visit (HIR::RangeFromExpr &expr)
 void
 ExprStmtBuilder::visit (HIR::RangeToExpr &expr)
 {
-  auto to = visit_expr (*expr.get_to_expr ());
+  auto to = visit_expr (expr.get_to_expr ());
   return_expr (new InitializerExpr ({to}), lookup_type (expr),
 	       expr.get_locus ());
 }
@@ -469,8 +470,8 @@ ExprStmtBuilder::visit (HIR::RangeFullExpr &expr)
 void
 ExprStmtBuilder::visit (HIR::RangeFromToInclExpr &expr)
 {
-  auto from = visit_expr (*expr.get_from_expr ());
-  auto to = visit_expr (*expr.get_to_expr ());
+  auto from = visit_expr (expr.get_from_expr ());
+  auto to = visit_expr (expr.get_to_expr ());
   return_expr (new InitializerExpr ({from, to}), lookup_type (expr),
 	       expr.get_locus ());
 }
@@ -478,7 +479,7 @@ ExprStmtBuilder::visit (HIR::RangeFromToInclExpr &expr)
 void
 ExprStmtBuilder::visit (HIR::RangeToInclExpr &expr)
 {
-  auto to = visit_expr (*expr.get_to_expr ());
+  auto to = visit_expr (expr.get_to_expr ());
   return_expr (new InitializerExpr ({to}), lookup_type (expr),
 	       expr.get_locus ());
 }
@@ -489,9 +490,9 @@ ExprStmtBuilder::visit (HIR::ReturnExpr &ret)
   if (ret.has_return_expr ())
     {
       push_assignment (RETURN_VALUE_PLACE,
-		       move_place (visit_expr (*ret.get_expr ()),
-				   ret.get_expr ()->get_locus ()),
-		       ret.get_expr ()->get_locus ());
+		       move_place (visit_expr (ret.get_expr ()),
+				   ret.get_expr ().get_locus ()),
+		       ret.get_expr ().get_locus ());
     }
   unwind_until (ROOT_SCOPE);
   push_return (ret.get_locus ());
@@ -509,7 +510,7 @@ ExprStmtBuilder::visit (HIR::LoopExpr &expr)
 {
   auto loop = setup_loop (expr);
 
-  std::ignore = visit_expr (*expr.get_loop_block ());
+  std::ignore = visit_expr (expr.get_loop_block ());
   if (!ctx.get_current_bb ().is_terminated ())
     push_goto (loop.continue_bb);
 
@@ -521,12 +522,12 @@ ExprStmtBuilder::visit (HIR::WhileLoopExpr &expr)
 {
   auto loop = setup_loop (expr);
 
-  auto cond_val = visit_expr (*expr.get_predicate_expr ());
+  auto cond_val = visit_expr (expr.get_predicate_expr ());
   auto body_bb = new_bb ();
   push_switch (cond_val, expr.get_locus (), {body_bb, loop.break_bb});
 
   ctx.current_bb = body_bb;
-  std::ignore = visit_expr (*expr.get_loop_block ());
+  std::ignore = visit_expr (expr.get_loop_block ());
   push_goto (loop.continue_bb);
 
   ctx.current_bb = loop.break_bb;
@@ -544,15 +545,15 @@ ExprStmtBuilder::visit (HIR::IfExpr &expr)
 {
   // If without else cannot return a non-unit value (see [E0317]).
 
-  if (expr.get_if_block ()->statements.empty ())
+  if (expr.get_if_block ().statements.empty ())
     return;
 
-  push_switch (visit_expr (*expr.get_if_condition ()), expr.get_locus ());
+  push_switch (visit_expr (expr.get_if_condition ()), expr.get_locus ());
   BasicBlockId if_block = ctx.current_bb;
 
   ctx.current_bb = new_bb ();
   BasicBlockId then_start_block = ctx.current_bb;
-  std::ignore = visit_expr (*expr.get_if_block ());
+  std::ignore = visit_expr (expr.get_if_block ());
   if (!ctx.get_current_bb ().is_terminated ())
     push_goto (INVALID_BB); // Resolved later.
   BasicBlockId then_end_block = ctx.current_bb;
@@ -573,8 +574,8 @@ ExprStmtBuilder::visit (HIR::IfExpr &expr)
 void
 ExprStmtBuilder::visit (HIR::IfExprConseqElse &expr)
 {
-  push_switch (move_place (visit_expr (*expr.get_if_condition ()),
-			   expr.get_if_condition ()->get_locus ()),
+  push_switch (move_place (visit_expr (expr.get_if_condition ()),
+			   expr.get_if_condition ().get_locus ()),
 	       expr.get_locus ());
   BasicBlockId if_end_bb = ctx.current_bb;
 
@@ -582,14 +583,14 @@ ExprStmtBuilder::visit (HIR::IfExprConseqElse &expr)
 
   ctx.current_bb = new_bb ();
   BasicBlockId then_start_bb = ctx.current_bb;
-  std::ignore = visit_expr (*expr.get_if_block (), result);
+  std::ignore = visit_expr (expr.get_if_block (), result);
   if (!ctx.get_current_bb ().is_terminated ())
     push_goto (INVALID_BB); // Resolved later.
   BasicBlockId then_end_bb = ctx.current_bb;
 
   ctx.current_bb = new_bb ();
   BasicBlockId else_start_bb = ctx.current_bb;
-  std::ignore = visit_expr (*expr.get_else_block (), result);
+  std::ignore = visit_expr (expr.get_else_block (), result);
   if (!ctx.get_current_bb ().is_terminated ())
     push_goto (INVALID_BB); // Resolved later.
   BasicBlockId else_end_bb = ctx.current_bb;
@@ -690,35 +691,35 @@ ExprStmtBuilder::visit (HIR::LetStmt &stmt)
   tl::optional<TyTy::BaseType *> type_annotation;
 
   if (stmt.has_type ())
-    type_annotation = lookup_type (*stmt.get_type ());
+    type_annotation = lookup_type (stmt.get_type ());
 
-  if (stmt.get_pattern ()->get_pattern_type () == HIR::Pattern::IDENTIFIER)
+  if (stmt.get_pattern ().get_pattern_type () == HIR::Pattern::IDENTIFIER)
     {
       // Only if a pattern is just an identifier, no destructuring is needed.
       // Hoverer PatternBindingBuilder cannot change existing temporary
       // (init expr is evaluated before pattern binding) into a
       // variable, so it would emit extra assignment.
-      auto var = declare_variable (stmt.get_pattern ()->get_mappings ());
+      auto var = declare_variable (stmt.get_pattern ().get_mappings ());
       if (stmt.has_type ())
-	push_user_type_ascription (var, lookup_type (*stmt.get_type ()));
+	push_user_type_ascription (var, lookup_type (stmt.get_type ()));
 
       if (stmt.has_init_expr ())
-	std::ignore = visit_expr (*stmt.get_init_expr (), var);
+	std::ignore = visit_expr (stmt.get_init_expr (), var);
     }
   else
     {
       if (stmt.has_init_expr ())
-	init = visit_expr (*stmt.get_init_expr ());
+	init = visit_expr (stmt.get_init_expr ());
 
       PatternBindingBuilder (ctx, init, type_annotation)
-	.go (*stmt.get_pattern ());
+	.go (stmt.get_pattern ());
     }
 }
 
 void
 ExprStmtBuilder::visit (HIR::ExprStmt &stmt)
 {
-  PlaceId result = visit_expr (*stmt.get_expr ());
+  PlaceId result = visit_expr (stmt.get_expr ());
   // We must read the value for current liveness and we must not store it into
   // the same place.
   if (result != INVALID_PLACE)
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h b/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h
index 8c01c501c36c..3bc622cda72a 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h
@@ -63,16 +63,16 @@ public:
 protected:
   void visit (HIR::LazyBooleanExpr &expr) override
   {
-    auto lhs = visit_expr (*expr.get_lhs ());
-    push_switch (move_place (lhs, expr.get_lhs ()->get_locus ()),
+    auto lhs = visit_expr (expr.get_lhs ());
+    push_switch (move_place (lhs, expr.get_lhs ().get_locus ()),
 		 expr.get_locus (), {short_circuit_bb});
 
     start_new_consecutive_bb ();
-    return_place (visit_expr (*expr.get_rhs ()), expr.get_locus ());
+    return_place (visit_expr (expr.get_rhs ()), expr.get_locus ());
   }
   void visit (HIR::GroupedExpr &expr) override
   {
-    expr.get_expr_in_parens ()->accept_vis (*this);
+    expr.get_expr_in_parens ().accept_vis (*this);
   }
 
 protected:
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.cc b/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.cc
index 723ff7334b62..ee37bb09bc43 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.cc
@@ -50,7 +50,7 @@ PatternBindingBuilder::visit (HIR::ReferencePattern &pattern)
     return ty->as<TyTy::ReferenceType> ()->get_base ();
   });
 
-  pattern.get_referenced_pattern ()->accept_vis (*this);
+  pattern.get_referenced_pattern ().accept_vis (*this);
 }
 
 void
@@ -107,7 +107,7 @@ PatternBindingBuilder::visit (HIR::StructPattern &pattern)
 
 	    init = init.map ([&] (PlaceId id) {
 	      return ctx.place_db.lookup_or_add_path (
-		Place::FIELD, lookup_type (*tuple->get_tuple_pattern ()), id,
+		Place::FIELD, lookup_type (tuple->get_tuple_pattern ()), id,
 		tuple->get_index ());
 	    });
 
@@ -120,7 +120,7 @@ PatternBindingBuilder::visit (HIR::StructPattern &pattern)
 		->get_field_type ();
 	    });
 
-	    tuple->get_tuple_pattern ()->accept_vis (*this);
+	    tuple->get_tuple_pattern ().accept_vis (*this);
 	    break;
 	  }
 	  case HIR::StructPatternField::IDENT_PAT: {
@@ -136,7 +136,7 @@ PatternBindingBuilder::visit (HIR::StructPattern &pattern)
 						    field_ty->get_field_type (),
 						    saved.init.value (),
 						    field_index);
-	    ident_field->get_pattern ()->accept_vis (*this);
+	    ident_field->get_pattern ().accept_vis (*this);
 	    break;
 	  }
 	  case HIR::StructPatternField::IDENT: {
@@ -197,17 +197,17 @@ PatternBindingBuilder::visit (HIR::TuplePattern &pattern)
   SavedState saved (this);
 
   size_t index = 0;
-  switch (pattern.get_items ()->get_item_type ())
+  switch (pattern.get_items ().get_item_type ())
     {
       case HIR::TuplePatternItems::MULTIPLE: {
 	auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
-	  *pattern.get_items ());
+	  pattern.get_items ());
 	visit_tuple_fields (items.get_patterns (), saved, index);
 	break;
       }
       case HIR::TuplePatternItems::RANGED: {
 	auto &items
-	  = static_cast<HIR::TuplePatternItemsRanged &> (*pattern.get_items ());
+	  = static_cast<HIR::TuplePatternItemsRanged &> (pattern.get_items ());
 
 	auto tyty = ctx.place_db[init.value ()].tyty;
 	rust_assert (tyty->get_kind () == TyTy::TUPLE);
@@ -242,11 +242,11 @@ PatternBindingBuilder::visit (HIR::TupleStructPattern &pattern)
   });
 
   size_t index = 0;
-  switch (pattern.get_items ()->get_item_type ())
+  switch (pattern.get_items ().get_item_type ())
     {
       case HIR::TupleStructItems::RANGED: {
 	auto &items
-	  = static_cast<HIR::TupleStructItemsRange &> (*pattern.get_items ());
+	  = static_cast<HIR::TupleStructItemsRange &> (pattern.get_items ());
 
 	rust_assert (type->get_kind () == TyTy::ADT);
 	auto adt_ty = static_cast<TyTy::ADTType *> (type);
@@ -263,7 +263,7 @@ PatternBindingBuilder::visit (HIR::TupleStructPattern &pattern)
       }
       case HIR::TupleStructItems::MULTIPLE: {
 	auto &items
-	  = static_cast<HIR::TupleStructItemsNoRange &> (*pattern.get_items ());
+	  = static_cast<HIR::TupleStructItemsNoRange &> (pattern.get_items ());
 	visit_tuple_fields (items.get_patterns (), saved, index);
 	break;
       }
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.h b/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.h
index 5d4b85a716db..33ecd2356c79 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.h
@@ -91,6 +91,7 @@ public:
   void visit (HIR::QualifiedPathInExpression &expression) override {}
   void visit (HIR::RangePattern &pattern) override {}
 };
+
 } // namespace BIR
 } // namespace Rust
 
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h b/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
index fefdd534cb16..18ddc19db1dd 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
@@ -52,12 +52,12 @@ public:
   }
   void visit (HIR::StructExprFieldIdentifierValue &field) override
   {
-    auto value = ExprStmtBuilder (ctx).build (*field.get_value ());
+    auto value = ExprStmtBuilder (ctx).build (field.get_value ());
     handle_named_field (field, value);
   }
   void visit (HIR::StructExprFieldIndexValue &field) override
   {
-    auto value = ExprStmtBuilder (ctx).build (*field.get_value ());
+    auto value = ExprStmtBuilder (ctx).build (field.get_value ());
     coercion_site (value,
 		   struct_ty->get_field_at_index (field.get_tuple_index ())
 		     ->get_field_type ());
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder.h b/gcc/rust/checks/errors/borrowck/rust-bir-builder.h
index 63d326278c7f..e5bdb46b0be2 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder.h
@@ -49,7 +49,7 @@ public:
     for (auto &param : function.get_function_params ())
       handle_param (param);
 
-    handle_body (*function.get_definition ());
+    handle_body (function.get_definition ());
     auto region_hir_map
       = map_region_to_hir (function.get_generic_params (), ctx.fn_free_regions);
 
@@ -118,14 +118,14 @@ private:
 
   void handle_param (HIR::FunctionParam &param)
   {
-    auto param_type = lookup_type (*param.get_param_name ());
+    auto param_type = lookup_type (param.get_param_name ());
 
     auto &pattern = param.get_param_name ();
-    if (pattern->get_pattern_type () == HIR::Pattern::IDENTIFIER
-	&& !static_cast<HIR::IdentifierPattern &> (*pattern).get_is_ref ())
+    if (pattern.get_pattern_type () == HIR::Pattern::IDENTIFIER
+	&& !static_cast<HIR::IdentifierPattern &> (pattern).get_is_ref ())
       {
 	// Avoid useless temporary variable for parameter to look like MIR.
-	translated = declare_variable (pattern->get_mappings ());
+	translated = declare_variable (pattern.get_mappings ());
 	ctx.arguments.push_back (translated);
       }
     else
@@ -133,11 +133,9 @@ private:
 	translated = ctx.place_db.add_temporary (param_type);
 	ctx.arguments.push_back (translated);
 	PatternBindingBuilder (ctx, translated, tl::nullopt)
-	  .go (*param.get_param_name ());
+	  .go (param.get_param_name ());
       }
 
-    rust_assert (param.get_type () != nullptr);
-
     // Set parameter place to use functions regions, not the fresh ones.
     ctx.place_db[translated].regions
       = bind_regions (Resolver::TypeCheckContext::get ()
@@ -159,7 +157,7 @@ private:
 			     body.get_end_locus ());
 	  }
 	auto return_location = body.has_expr ()
-				 ? body.get_final_expr ()->get_locus ()
+				 ? body.get_final_expr ().get_locus ()
 				 : body.get_end_locus ();
 	push_return (return_location);
       }
diff --git a/gcc/rust/checks/errors/borrowck/rust-function-collector.h b/gcc/rust/checks/errors/borrowck/rust-function-collector.h
index bea438c54451..5de503d441cc 100644
--- a/gcc/rust/checks/errors/borrowck/rust-function-collector.h
+++ b/gcc/rust/checks/errors/borrowck/rust-function-collector.h
@@ -56,13 +56,13 @@ protected:
   void visit (HIR::Function &function) override
   {
     functions.push_back (&function);
-    function.get_definition ()->accept_vis (*this);
+    function.get_definition ().accept_vis (*this);
   }
 
   void visit (HIR::ClosureExpr &closure) override
   {
     closures.push_back (&closure);
-    closure.get_expr ()->accept_vis (*this);
+    closure.get_expr ().accept_vis (*this);
   }
 
   // TODO: recurse for nested closures and functions.
diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
index fa2de9c3f400..3cbf47ecc8b1 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
@@ -267,16 +267,13 @@ PrivacyReporter::check_base_type_privacy (Analysis::NodeMapping &node_mappings,
 }
 
 void
-PrivacyReporter::check_type_privacy (const HIR::Type *type)
+PrivacyReporter::check_type_privacy (const HIR::Type &type)
 {
-  rust_assert (type);
-
   TyTy::BaseType *lookup = nullptr;
-  rust_assert (
-    ty_ctx.lookup_type (type->get_mappings ().get_hirid (), &lookup));
+  rust_assert (ty_ctx.lookup_type (type.get_mappings ().get_hirid (), &lookup));
 
-  auto node_mappings = type->get_mappings ();
-  return check_base_type_privacy (node_mappings, lookup, type->get_locus ());
+  auto node_mappings = type.get_mappings ();
+  return check_base_type_privacy (node_mappings, lookup, type.get_locus ());
 }
 
 void
@@ -326,100 +323,98 @@ PrivacyReporter::visit (HIR::LiteralExpr &)
 void
 PrivacyReporter::visit (HIR::BorrowExpr &expr)
 {
-  expr.get_expr ()->accept_vis (*this);
+  expr.get_expr ().accept_vis (*this);
 }
 
 void
 PrivacyReporter::visit (HIR::DereferenceExpr &expr)
 {
-  expr.get_expr ()->accept_vis (*this);
+  expr.get_expr ().accept_vis (*this);
 }
 
 void
 PrivacyReporter::visit (HIR::ErrorPropagationExpr &expr)
 {
-  expr.get_expr ()->accept_vis (*this);
+  expr.get_expr ().accept_vis (*this);
 }
 
 void
 PrivacyReporter::visit (HIR::NegationExpr &expr)
 {
-  expr.get_expr ()->accept_vis (*this);
+  expr.get_expr ().accept_vis (*this);
 }
 
 void
 PrivacyReporter::visit (HIR::ArithmeticOrLogicalExpr &expr)
 {
-  expr.get_lhs ()->accept_vis (*this);
-  expr.get_rhs ()->accept_vis (*this);
+  expr.get_lhs ().accept_vis (*this);
+  expr.get_rhs ().accept_vis (*this);
 }
 
 void
 PrivacyReporter::visit (HIR::ComparisonExpr &expr)
 {
-  expr.get_lhs ()->accept_vis (*this);
-  expr.get_rhs ()->accept_vis (*this);
+  expr.get_lhs ().accept_vis (*this);
+  expr.get_rhs ().accept_vis (*this);
 }
 
 void
 PrivacyReporter::visit (HIR::LazyBooleanExpr &expr)
 {
-  expr.get_lhs ()->accept_vis (*this);
-  expr.get_rhs ()->accept_vis (*this);
+  expr.get_lhs ().accept_vis (*this);
+  expr.get_rhs ().accept_vis (*this);
 }
 
 void
 PrivacyReporter::visit (HIR::TypeCastExpr &expr)
 {
-  expr.get_expr ()->accept_vis (*this);
+  expr.get_expr ().accept_vis (*this);
 }
 
 void
 PrivacyReporter::visit (HIR::AssignmentExpr &expr)
 {
-  expr.get_lhs ()->accept_vis (*this);
-  expr.get_rhs ()->accept_vis (*this);
+  expr.get_lhs ().accept_vis (*this);
+  expr.get_rhs ().accept_vis (*this);
 }
 
 void
 PrivacyReporter::visit (HIR::CompoundAssignmentExpr &expr)
 {
-  expr.get_lhs ()->accept_vis (*this);
-  expr.get_rhs ()->accept_vis (*this);
+  expr.get_lhs ().accept_vis (*this);
+  expr.get_rhs ().accept_vis (*this);
 }
 
 void
 PrivacyReporter::visit (HIR::GroupedExpr &expr)
 {
-  expr.get_expr_in_parens ()->accept_vis (*this);
+  expr.get_expr_in_parens ().accept_vis (*this);
 }
 
 void
 PrivacyReporter::visit (HIR::ArrayExpr &expr)
 {
-  HIR::ArrayElems &elements = *expr.get_internal_elements ();
+  HIR::ArrayElems &elements = expr.get_internal_elements ();
   switch (elements.get_array_expr_type ())
     {
       case HIR::ArrayElems::ArrayExprType::VALUES: {
-	HIR::ArrayElemsValues &elems
-	  = static_cast<HIR::ArrayElemsValues &> (elements);
+	auto &elems = static_cast<HIR::ArrayElemsValues &> (elements);
 	for (auto &value : elems.get_values ())
 	  value->accept_vis (*this);
       }
       return;
 
     case HIR::ArrayElems::ArrayExprType::COPIED:
-      HIR::ArrayElemsCopied &elems
-	= static_cast<HIR::ArrayElemsCopied &> (elements);
-      elems.get_elem_to_copy ()->accept_vis (*this);
+      auto &elems = static_cast<HIR::ArrayElemsCopied &> (elements);
+      elems.get_elem_to_copy ().accept_vis (*this);
     }
 }
 
 void
 PrivacyReporter::visit (HIR::ArrayIndexExpr &expr)
 {
-  expr.get_array_expr ()->accept_vis (*this);
-  expr.get_index_expr ()->accept_vis (*this);
+  expr.get_array_expr ().accept_vis (*this);
+  expr.get_index_expr ().accept_vis (*this);
 }
 
 void
@@ -432,7 +427,7 @@ PrivacyReporter::visit (HIR::TupleExpr &expr)
 void
 PrivacyReporter::visit (HIR::TupleIndexExpr &expr)
 {
-  expr.get_tuple_expr ()->accept_vis (*this);
+  expr.get_tuple_expr ().accept_vis (*this);
 }
 
 void
@@ -448,13 +443,13 @@ PrivacyReporter::visit (HIR::StructExprFieldIdentifier &)
 void
 PrivacyReporter::visit (HIR::StructExprFieldIdentifierValue &field)
 {
-  field.get_value ()->accept_vis (*this);
+  field.get_value ().accept_vis (*this);
 }
 
 void
 PrivacyReporter::visit (HIR::StructExprFieldIndexValue &field)
 {
-  field.get_value ()->accept_vis (*this);
+  field.get_value ().accept_vis (*this);
 }
 
 void
@@ -467,7 +462,7 @@ PrivacyReporter::visit (HIR::StructExprStructFields &expr)
 void
 PrivacyReporter::visit (HIR::CallExpr &expr)
 {
-  expr.get_fnexpr ()->accept_vis (*this);
+  expr.get_fnexpr ().accept_vis (*this);
 
   for (auto &param : expr.get_arguments ())
     param->accept_vis (*this);
@@ -476,7 +471,7 @@ PrivacyReporter::visit (HIR::CallExpr &expr)
 void
 PrivacyReporter::visit (HIR::MethodCallExpr &expr)
 {
-  expr.get_receiver ()->accept_vis (*this);
+  expr.get_receiver ().accept_vis (*this);
 
   for (auto &param : expr.get_arguments ())
     param->accept_vis (*this);
@@ -485,7 +480,7 @@ PrivacyReporter::visit (HIR::MethodCallExpr &expr)
 void
 PrivacyReporter::visit (HIR::FieldAccessExpr &expr)
 {
-  expr.get_receiver_expr ()->accept_vis (*this);
+  expr.get_receiver_expr ().accept_vis (*this);
 
   // FIXME: We should also check if the field is public?
 }
@@ -503,8 +498,7 @@ PrivacyReporter::visit (HIR::BlockExpr &expr)
     stmt->accept_vis (*this);
 
   auto &last_expr = expr.get_final_expr ();
-  if (last_expr)
-    last_expr->accept_vis (*this);
+  last_expr.accept_vis (*this);
 }
 
 void
@@ -515,27 +509,26 @@ void
 PrivacyReporter::visit (HIR::BreakExpr &expr)
 {
   auto &break_expr = expr.get_expr ();
-  if (break_expr)
-    break_expr->accept_vis (*this);
+  break_expr.accept_vis (*this);
 }
 
 void
 PrivacyReporter::visit (HIR::RangeFromToExpr &expr)
 {
-  expr.get_from_expr ()->accept_vis (*this);
-  expr.get_to_expr ()->accept_vis (*this);
+  expr.get_from_expr ().accept_vis (*this);
+  expr.get_to_expr ().accept_vis (*this);
 }
 
 void
 PrivacyReporter::visit (HIR::RangeFromExpr &expr)
 {
-  expr.get_from_expr ()->accept_vis (*this);
+  expr.get_from_expr ().accept_vis (*this);
 }
 
 void
 PrivacyReporter::visit (HIR::RangeToExpr &expr)
 {
-  expr.get_to_expr ()->accept_vis (*this);
+  expr.get_to_expr ().accept_vis (*this);
 }
 
 void
@@ -545,8 +538,8 @@ PrivacyReporter::visit (HIR::RangeFullExpr &)
 void
 PrivacyReporter::visit (HIR::RangeFromToInclExpr &expr)
 {
-  expr.get_from_expr ()->accept_vis (*this);
-  expr.get_to_expr ()->accept_vis (*this);
+  expr.get_from_expr ().accept_vis (*this);
+  expr.get_to_expr ().accept_vis (*this);
 }
 
 void
@@ -558,55 +551,54 @@ PrivacyReporter::visit (HIR::RangeToInclExpr &)
 void
 PrivacyReporter::visit (HIR::ReturnExpr &expr)
 {
-  if (expr.get_expr ())
-    expr.get_expr ()->accept_vis (*this);
+  expr.get_expr ().accept_vis (*this);
 }
 
 void
 PrivacyReporter::visit (HIR::UnsafeBlockExpr &expr)
 {
-  expr.get_block_expr ()->accept_vis (*this);
+  expr.get_block_expr ().accept_vis (*this);
 }
 
 void
 PrivacyReporter::visit (HIR::LoopExpr &expr)
 {
-  expr.get_loop_block ()->accept_vis (*this);
+  expr.get_loop_block ().accept_vis (*this);
 }
 
 void
 PrivacyReporter::visit (HIR::WhileLoopExpr &expr)
 {
-  expr.get_predicate_expr ()->accept_vis (*this);
-  expr.get_loop_block ()->accept_vis (*this);
+  expr.get_predicate_expr ().accept_vis (*this);
+  expr.get_loop_block ().accept_vis (*this);
 }
 
 void
 PrivacyReporter::visit (HIR::WhileLetLoopExpr &expr)
 {
-  expr.get_cond ()->accept_vis (*this);
-  expr.get_loop_block ()->accept_vis (*this);
+  expr.get_cond ().accept_vis (*this);
+  expr.get_loop_block ().accept_vis (*this);
 }
 
 void
 PrivacyReporter::visit (HIR::IfExpr &expr)
 {
-  expr.get_if_condition ()->accept_vis (*this);
-  expr.get_if_block ()->accept_vis (*this);
+  expr.get_if_condition ().accept_vis (*this);
+  expr.get_if_block ().accept_vis (*this);
 }
 
 void
 PrivacyReporter::visit (HIR::IfExprConseqElse &expr)
 {
-  expr.get_if_condition ()->accept_vis (*this);
-  expr.get_if_block ()->accept_vis (*this);
-  expr.get_else_block ()->accept_vis (*this);
+  expr.get_if_condition ().accept_vis (*this);
+  expr.get_if_block ().accept_vis (*this);
+  expr.get_else_block ().accept_vis (*this);
 }
 
 void
 PrivacyReporter::visit (HIR::MatchExpr &expr)
 {
-  expr.get_scrutinee_expr ()->accept_vis (*this);
+  expr.get_scrutinee_expr ().accept_vis (*this);
 }
 
 void
@@ -649,9 +641,9 @@ void
 PrivacyReporter::visit (HIR::Function &function)
 {
   for (auto &param : function.get_function_params ())
-    check_type_privacy (param.get_type ().get ());
+    check_type_privacy (param.get_type ());
 
-  function.get_definition ()->accept_vis (*this);
+  function.get_definition ().accept_vis (*this);
 }
 
 void
@@ -708,14 +700,14 @@ void
 PrivacyReporter::visit (HIR::ConstantItem &const_item)
 {
   // TODO: We need to visit the type
-  const_item.get_expr ()->accept_vis (*this);
+  const_item.get_expr ().accept_vis (*this);
 }
 
 void
 PrivacyReporter::visit (HIR::StaticItem &static_item)
 {
   // TODO: We need to visit the type
-  static_item.get_expr ()->accept_vis (*this);
+  static_item.get_expr ().accept_vis (*this);
 }
 
 void
@@ -748,17 +740,15 @@ PrivacyReporter::visit (HIR::EmptyStmt &)
 void
 PrivacyReporter::visit (HIR::LetStmt &stmt)
 {
-  if (stmt.get_type ())
-    check_type_privacy (stmt.get_type ().get ());
+  check_type_privacy (stmt.get_type ());
 
-  if (stmt.get_init_expr ())
-    stmt.get_init_expr ()->accept_vis (*this);
+  stmt.get_init_expr ().accept_vis (*this);
 }
 
 void
 PrivacyReporter::visit (HIR::ExprStmt &stmt)
 {
-  stmt.get_expr ()->accept_vis (*this);
+  stmt.get_expr ().accept_vis (*this);
 }
 
 } // namespace Privacy
diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
index b9cc230d5db1..5111a3e656d8 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
@@ -75,7 +75,7 @@ types
    * @param type Reference to an explicit type used in a statement, expression
    * 		or parameter
    */
-  void check_type_privacy (const HIR::Type *type);
+  void check_type_privacy (const HIR::Type &type);
 
   virtual void visit (HIR::StructExprFieldIdentifier &field);
   virtual void visit (HIR::StructExprFieldIdentifierValue &field);
diff --git a/gcc/rust/checks/errors/privacy/rust-reachability.cc b/gcc/rust/checks/errors/privacy/rust-reachability.cc
index 9e0cb821814c..1e57674b4024 100644
--- a/gcc/rust/checks/errors/privacy/rust-reachability.cc
+++ b/gcc/rust/checks/errors/privacy/rust-reachability.cc
@@ -132,7 +132,7 @@ ReachabilityVisitor::visit (HIR::StructStruct &struct_item)
     {
       for (auto &field : struct_item.get_fields ())
 	if (field.get_visibility ().is_public ())
-	  ctx.update_reachability (field.get_field_type ()->get_mappings (),
+	  ctx.update_reachability (field.get_field_type ().get_mappings (),
 				   struct_reach);
     }
 
diff --git a/gcc/rust/checks/errors/rust-const-checker.cc b/gcc/rust/checks/errors/rust-const-checker.cc
index 1e0ebd297989..420db8fb8b20 100644
--- a/gcc/rust/checks/errors/rust-const-checker.cc
+++ b/gcc/rust/checks/errors/rust-const-checker.cc
@@ -161,72 +161,72 @@ ConstChecker::visit (LiteralExpr &)
 void
 ConstChecker::visit (BorrowExpr &expr)
 {
-  expr.get_expr ()->accept_vis (*this);
+  expr.get_expr ().accept_vis (*this);
 }
 
 void
 ConstChecker::visit (DereferenceExpr &expr)
 {
-  expr.get_expr ()->accept_vis (*this);
+  expr.get_expr ().accept_vis (*this);
 }
 
 void
 ConstChecker::visit (ErrorPropagationExpr &expr)
 {
-  expr.get_expr ()->accept_vis (*this);
+  expr.get_expr ().accept_vis (*this);
 }
 
 void
 ConstChecker::visit (NegationExpr &expr)
 {
-  expr.get_expr ()->accept_vis (*this);
+  expr.get_expr ().accept_vis (*this);
 }
 
 void
 ConstChecker::visit (ArithmeticOrLogicalExpr &expr)
 {
-  expr.get_lhs ()->accept_vis (*this);
-  expr.get_rhs ()->accept_vis (*this);
+  expr.get_lhs ().accept_vis (*this);
+  expr.get_rhs ().accept_vis (*this);
 }
 
 void
 ConstChecker::visit (ComparisonExpr &expr)
 {
-  expr.get_lhs ()->accept_vis (*this);
-  expr.get_rhs ()->accept_vis (*this);
+  expr.get_lhs ().accept_vis (*this);
+  expr.get_rhs ().accept_vis (*this);
 }
 
 void
 ConstChecker::visit (LazyBooleanExpr &expr)
 {
-  expr.get_lhs ()->accept_vis (*this);
-  expr.get_rhs ()->accept_vis (*this);
+  expr.get_lhs ().accept_vis (*this);
+  expr.get_rhs ().accept_vis (*this);
 }
 
 void
 ConstChecker::visit (TypeCastExpr &expr)
 {
-  expr.get_expr ()->accept_vis (*this);
+  expr.get_expr ().accept_vis (*this);
 }
 
 void
 ConstChecker::visit (AssignmentExpr &expr)
 {
-  expr.get_lhs ()->accept_vis (*this);
-  expr.get_rhs ()->accept_vis (*this);
+  expr.get_lhs ().accept_vis (*this);
+  expr.get_rhs ().accept_vis (*this);
 }
 
 void
 ConstChecker::visit (CompoundAssignmentExpr &expr)
 {
-  expr.get_lhs ()->accept_vis (*this);
-  expr.get_rhs ()->accept_vis (*this);
+  expr.get_lhs ().accept_vis (*this);
+  expr.get_rhs ().accept_vis (*this);
 }
 
 void
 ConstChecker::visit (GroupedExpr &expr)
 {
-  expr.get_expr_in_parens ()->accept_vis (*this);
+  expr.get_expr_in_parens ().accept_vis (*this);
 }
 
 void
@@ -239,11 +239,11 @@ ConstChecker::visit (ArrayElemsValues &elems)
 void
 ConstChecker::visit (ArrayElemsCopied &elems)
 {
-  elems.get_elem_to_copy ()->accept_vis (*this);
+  elems.get_elem_to_copy ().accept_vis (*this);
 
   const_context.enter (elems.get_mappings ().get_hirid ());
 
-  elems.get_num_copies_expr ()->accept_vis (*this);
+  elems.get_num_copies_expr ().accept_vis (*this);
 
   const_context.exit ();
 }
@@ -251,14 +251,14 @@ ConstChecker::visit (ArrayElemsCopied &elems)
 void
 ConstChecker::visit (ArrayExpr &expr)
 {
-  expr.get_internal_elements ()->accept_vis (*this);
+  expr.get_internal_elements ().accept_vis (*this);
 }
 
 void
 ConstChecker::visit (ArrayIndexExpr &expr)
 {
-  expr.get_array_expr ()->accept_vis (*this);
-  expr.get_index_expr ()->accept_vis (*this);
+  expr.get_array_expr ().accept_vis (*this);
+  expr.get_index_expr ().accept_vis (*this);
 }
 
 void
@@ -271,7 +271,7 @@ ConstChecker::visit (TupleExpr &expr)
 void
 ConstChecker::visit (TupleIndexExpr &expr)
 {
-  expr.get_tuple_expr ()->accept_vis (*this);
+  expr.get_tuple_expr ().accept_vis (*this);
 }
 
 void
@@ -285,13 +285,13 @@ ConstChecker::visit (StructExprFieldIdentifier &)
 void
 ConstChecker::visit (StructExprFieldIdentifierValue &field)
 {
-  field.get_value ()->accept_vis (*this);
+  field.get_value ().accept_vis (*this);
 }
 
 void
 ConstChecker::visit (StructExprFieldIndexValue &field)
 {
-  field.get_value ()->accept_vis (*this);
+  field.get_value ().accept_vis (*this);
 }
 
 void
@@ -352,10 +352,10 @@ ConstChecker::check_function_call (HirId fn_id, location_t locus)
 void
 ConstChecker::visit (CallExpr &expr)
 {
-  if (!expr.get_fnexpr ())
+  if (!expr.has_fnexpr ())
     return;
 
-  NodeId ast_node_id = expr.get_fnexpr ()->get_mappings ().get_nodeid ();
+  NodeId ast_node_id = expr.get_fnexpr ().get_mappings ().get_nodeid ();
   NodeId ref_node_id;
 
   if (flag_name_resolution_2_0)
@@ -388,7 +388,7 @@ ConstChecker::visit (CallExpr &expr)
 void
 ConstChecker::visit (MethodCallExpr &expr)
 {
-  expr.get_receiver ()->accept_vis (*this);
+  expr.get_receiver ().accept_vis (*this);
 
   for (auto &arg : expr.get_arguments ())
     arg->accept_vis (*this);
@@ -397,13 +397,13 @@ ConstChecker::visit (MethodCallExpr &expr)
 void
 ConstChecker::visit (FieldAccessExpr &expr)
 {
-  expr.get_receiver_expr ()->accept_vis (*this);
+  expr.get_receiver_expr ().accept_vis (*this);
 }
 
 void
 ConstChecker::visit (ClosureExpr &expr)
 {
-  expr.get_expr ()->accept_vis (*this);
+  expr.get_expr ().accept_vis (*this);
 }
 
 void
@@ -413,7 +413,7 @@ ConstChecker::visit (BlockExpr &expr)
     stmt->accept_vis (*this);
 
   if (expr.has_expr ())
-    expr.get_final_expr ()->accept_vis (*this);
+    expr.get_final_expr ().accept_vis (*this);
 }
 
 void
@@ -424,26 +424,26 @@ void
 ConstChecker::visit (BreakExpr &expr)
 {
   if (expr.has_break_expr ())
-    expr.get_expr ()->accept_vis (*this);
+    expr.get_expr ().accept_vis (*this);
 }
 
 void
 ConstChecker::visit (RangeFromToExpr &expr)
 {
-  expr.get_from_expr ()->accept_vis (*this);
-  expr.get_to_expr ()->accept_vis (*this);
+  expr.get_from_expr ().accept_vis (*this);
+  expr.get_to_expr ().accept_vis (*this);
 }
 
 void
 ConstChecker::visit (RangeFromExpr &expr)
 {
-  expr.get_from_expr ()->accept_vis (*this);
+  expr.get_from_expr ().accept_vis (*this);
 }
 
 void
 ConstChecker::visit (RangeToExpr &expr)
 {
-  expr.get_to_expr ()->accept_vis (*this);
+  expr.get_to_expr ().accept_vis (*this);
 }
 
 void
@@ -453,8 +453,8 @@ ConstChecker::visit (RangeFullExpr &)
 void
 ConstChecker::visit (RangeFromToInclExpr &expr)
 {
-  expr.get_from_expr ()->accept_vis (*this);
-  expr.get_to_expr ()->accept_vis (*this);
+  expr.get_from_expr ().accept_vis (*this);
+  expr.get_to_expr ().accept_vis (*this);
 }
 
 void
@@ -467,57 +467,57 @@ void
 ConstChecker::visit (ReturnExpr &expr)
 {
   if (expr.has_return_expr ())
-    expr.get_expr ()->accept_vis (*this);
+    expr.get_expr ().accept_vis (*this);
 }
 
 void
 ConstChecker::visit (UnsafeBlockExpr &expr)
 {
-  expr.get_block_expr ()->accept_vis (*this);
+  expr.get_block_expr ().accept_vis (*this);
 }
 
 void
 ConstChecker::visit (LoopExpr &expr)
 {
-  expr.get_loop_block ()->accept_vis (*this);
+  expr.get_loop_block ().accept_vis (*this);
 }
 
 void
 ConstChecker::visit (WhileLoopExpr &expr)
 {
-  expr.get_predicate_expr ()->accept_vis (*this);
-  expr.get_loop_block ()->accept_vis (*this);
+  expr.get_predicate_expr ().accept_vis (*this);
+  expr.get_loop_block ().accept_vis (*this);
 }
 
 void
 ConstChecker::visit (WhileLetLoopExpr &expr)
 {
-  expr.get_cond ()->accept_vis (*this);
-  expr.get_loop_block ()->accept_vis (*this);
+  expr.get_cond ().accept_vis (*this);
+  expr.get_loop_block ().accept_vis (*this);
 }
 
 void
 ConstChecker::visit (IfExpr &expr)
 {
-  expr.get_if_condition ()->accept_vis (*this);
-  expr.get_if_block ()->accept_vis (*this);
+  expr.get_if_condition ().accept_vis (*this);
+  expr.get_if_block ().accept_vis (*this);
 }
 
 void
 ConstChecker::visit (IfExprConseqElse &expr)
 {
-  expr.get_if_condition ()->accept_vis (*this);
-  expr.get_if_block ()->accept_vis (*this);
-  expr.get_else_block ()->accept_vis (*this);
+  expr.get_if_condition ().accept_vis (*this);
+  expr.get_if_block ().accept_vis (*this);
+  expr.get_else_block ().accept_vis (*this);
 }
 
 void
 ConstChecker::visit (MatchExpr &expr)
 {
-  expr.get_scrutinee_expr ()->accept_vis (*this);
+  expr.get_scrutinee_expr ().accept_vis (*this);
 
   for (auto &match_arm : expr.get_match_cases ())
-    match_arm.get_expr ()->accept_vis (*this);
+    match_arm.get_expr ().accept_vis (*this);
 }
 
 void
@@ -590,9 +590,9 @@ ConstChecker::visit (Function &function)
 				ConstGenericCtx::Function);
 
   for (auto &param : function.get_function_params ())
-    param.get_type ()->accept_vis (*this);
+    param.get_type ().accept_vis (*this);
 
-  function.get_definition ()->accept_vis (*this);
+  function.get_definition ().accept_vis (*this);
 
   if (const_fn)
     const_context.exit ();
@@ -636,7 +636,7 @@ ConstChecker::visit (EnumItemDiscriminant &item)
 {
   const_context.enter (item.get_mappings ().get_hirid ());
 
-  item.get_discriminant_expression ()->accept_vis (*this);
+  item.get_discriminant_expression ().accept_vis (*this);
 
   const_context.exit ();
 }
@@ -660,7 +660,7 @@ ConstChecker::visit (ConstantItem &const_item)
 {
   const_context.enter (const_item.get_mappings ().get_hirid ());
 
-  const_item.get_expr ()->accept_vis (*this);
+  const_item.get_expr ().accept_vis (*this);
 
   const_context.exit ();
 }
@@ -670,7 +670,7 @@ ConstChecker::visit (StaticItem &static_item)
 {
   const_context.enter (static_item.get_mappings ().get_hirid ());
 
-  static_item.get_expr ()->accept_vis (*this);
+  static_item.get_expr ().accept_vis (*this);
 
   const_context.exit ();
 }
@@ -679,14 +679,14 @@ void
 ConstChecker::visit (TraitItemFunc &item)
 {
   if (item.has_block_defined ())
-    item.get_block_expr ()->accept_vis (*this);
+    item.get_block_expr ().accept_vis (*this);
 }
 
 void
 ConstChecker::visit (TraitItemConst &item)
 {
   if (item.has_expr ())
-    item.get_expr ()->accept_vis (*this);
+    item.get_expr ().accept_vis (*this);
 }
 
 void
@@ -821,13 +821,13 @@ void
 ConstChecker::visit (LetStmt &stmt)
 {
   if (stmt.has_init_expr ())
-    stmt.get_init_expr ()->accept_vis (*this);
+    stmt.get_init_expr ().accept_vis (*this);
 }
 
 void
 ConstChecker::visit (ExprStmt &stmt)
 {
-  stmt.get_expr ()->accept_vis (*this);
+  stmt.get_expr ().accept_vis (*this);
 }
 
 void
@@ -875,7 +875,7 @@ ConstChecker::visit (ArrayType &type)
 {
   const_context.enter (type.get_mappings ().get_hirid ());
 
-  type.get_size_expr ()->accept_vis (*this);
+  type.get_size_expr ().accept_vis (*this);
 
   const_context.exit ();
 }
diff --git a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
index 8fb795b7b837..617d754c1819 100644
--- a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
+++ b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
@@ -92,72 +92,72 @@ PatternChecker::visit (LiteralExpr &)
 void
 PatternChecker::visit (BorrowExpr &expr)
 {
-  expr.get_expr ()->accept_vis (*this);
+  expr.get_expr ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (DereferenceExpr &expr)
 {
-  expr.get_expr ()->accept_vis (*this);
+  expr.get_expr ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (ErrorPropagationExpr &expr)
 {
-  expr.get_expr ()->accept_vis (*this);
+  expr.get_expr ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (NegationExpr &expr)
 {
-  expr.get_expr ()->accept_vis (*this);
+  expr.get_expr ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (ArithmeticOrLogicalExpr &expr)
 {
-  expr.get_lhs ()->accept_vis (*this);
-  expr.get_rhs ()->accept_vis (*this);
+  expr.get_lhs ().accept_vis (*this);
+  expr.get_rhs ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (ComparisonExpr &expr)
 {
-  expr.get_lhs ()->accept_vis (*this);
-  expr.get_rhs ()->accept_vis (*this);
+  expr.get_lhs ().accept_vis (*this);
+  expr.get_rhs ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (LazyBooleanExpr &expr)
 {
-  expr.get_lhs ()->accept_vis (*this);
-  expr.get_rhs ()->accept_vis (*this);
+  expr.get_lhs ().accept_vis (*this);
+  expr.get_rhs ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (TypeCastExpr &expr)
 {
-  expr.get_expr ()->accept_vis (*this);
+  expr.get_expr ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (AssignmentExpr &expr)
 {
-  expr.get_lhs ()->accept_vis (*this);
-  expr.get_rhs ()->accept_vis (*this);
+  expr.get_lhs ().accept_vis (*this);
+  expr.get_rhs ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (CompoundAssignmentExpr &expr)
 {
-  expr.get_lhs ()->accept_vis (*this);
-  expr.get_rhs ()->accept_vis (*this);
+  expr.get_lhs ().accept_vis (*this);
+  expr.get_rhs ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (GroupedExpr &expr)
 {
-  expr.get_expr_in_parens ()->accept_vis (*this);
+  expr.get_expr_in_parens ().accept_vis (*this);
 }
 
 void
@@ -170,20 +170,20 @@ PatternChecker::visit (ArrayElemsValues &elems)
 void
 PatternChecker::visit (ArrayElemsCopied &elems)
 {
-  elems.get_elem_to_copy ()->accept_vis (*this);
+  elems.get_elem_to_copy ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (ArrayExpr &expr)
 {
-  expr.get_internal_elements ()->accept_vis (*this);
+  expr.get_internal_elements ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (ArrayIndexExpr &expr)
 {
-  expr.get_array_expr ()->accept_vis (*this);
-  expr.get_index_expr ()->accept_vis (*this);
+  expr.get_array_expr ().accept_vis (*this);
+  expr.get_index_expr ().accept_vis (*this);
 }
 
 void
@@ -196,7 +196,7 @@ PatternChecker::visit (TupleExpr &expr)
 void
 PatternChecker::visit (TupleIndexExpr &expr)
 {
-  expr.get_tuple_expr ()->accept_vis (*this);
+  expr.get_tuple_expr ().accept_vis (*this);
 }
 
 void
@@ -210,13 +210,13 @@ PatternChecker::visit (StructExprFieldIdentifier &)
 void
 PatternChecker::visit (StructExprFieldIdentifierValue &field)
 {
-  field.get_value ()->accept_vis (*this);
+  field.get_value ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (StructExprFieldIndexValue &field)
 {
-  field.get_value ()->accept_vis (*this);
+  field.get_value ().accept_vis (*this);
 }
 
 void
@@ -233,10 +233,10 @@ PatternChecker::visit (StructExprStructBase &)
 void
 PatternChecker::visit (CallExpr &expr)
 {
-  if (!expr.get_fnexpr ())
+  if (!expr.has_fnexpr ())
     return;
 
-  NodeId ast_node_id = expr.get_fnexpr ()->get_mappings ().get_nodeid ();
+  NodeId ast_node_id = expr.get_fnexpr ().get_mappings ().get_nodeid ();
   NodeId ref_node_id;
   if (flag_name_resolution_2_0)
     {
@@ -266,7 +266,7 @@ PatternChecker::visit (CallExpr &expr)
 void
 PatternChecker::visit (MethodCallExpr &expr)
 {
-  expr.get_receiver ()->accept_vis (*this);
+  expr.get_receiver ().accept_vis (*this);
 
   for (auto &arg : expr.get_arguments ())
     arg->accept_vis (*this);
@@ -275,13 +275,13 @@ PatternChecker::visit (MethodCallExpr &expr)
 void
 PatternChecker::visit (FieldAccessExpr &expr)
 {
-  expr.get_receiver_expr ()->accept_vis (*this);
+  expr.get_receiver_expr ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (ClosureExpr &expr)
 {
-  expr.get_expr ()->accept_vis (*this);
+  expr.get_expr ().accept_vis (*this);
 }
 
 void
@@ -291,7 +291,7 @@ PatternChecker::visit (BlockExpr &expr)
     stmt->accept_vis (*this);
 
   if (expr.has_expr ())
-    expr.get_final_expr ()->accept_vis (*this);
+    expr.get_final_expr ().accept_vis (*this);
 }
 
 void
@@ -302,26 +302,26 @@ void
 PatternChecker::visit (BreakExpr &expr)
 {
   if (expr.has_break_expr ())
-    expr.get_expr ()->accept_vis (*this);
+    expr.get_expr ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (RangeFromToExpr &expr)
 {
-  expr.get_from_expr ()->accept_vis (*this);
-  expr.get_to_expr ()->accept_vis (*this);
+  expr.get_from_expr ().accept_vis (*this);
+  expr.get_to_expr ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (RangeFromExpr &expr)
 {
-  expr.get_from_expr ()->accept_vis (*this);
+  expr.get_from_expr ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (RangeToExpr &expr)
 {
-  expr.get_to_expr ()->accept_vis (*this);
+  expr.get_to_expr ().accept_vis (*this);
 }
 
 void
@@ -331,76 +331,76 @@ PatternChecker::visit (RangeFullExpr &)
 void
 PatternChecker::visit (RangeFromToInclExpr &expr)
 {
-  expr.get_from_expr ()->accept_vis (*this);
-  expr.get_to_expr ()->accept_vis (*this);
+  expr.get_from_expr ().accept_vis (*this);
+  expr.get_to_expr ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (RangeToInclExpr &expr)
 {
-  expr.get_to_expr ()->accept_vis (*this);
+  expr.get_to_expr ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (ReturnExpr &expr)
 {
   if (expr.has_return_expr ())
-    expr.get_expr ()->accept_vis (*this);
+    expr.get_expr ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (UnsafeBlockExpr &expr)
 {
-  expr.get_block_expr ()->accept_vis (*this);
+  expr.get_block_expr ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (LoopExpr &expr)
 {
-  expr.get_loop_block ()->accept_vis (*this);
+  expr.get_loop_block ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (WhileLoopExpr &expr)
 {
-  expr.get_predicate_expr ()->accept_vis (*this);
-  expr.get_loop_block ()->accept_vis (*this);
+  expr.get_predicate_expr ().accept_vis (*this);
+  expr.get_loop_block ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (WhileLetLoopExpr &expr)
 {
-  expr.get_cond ()->accept_vis (*this);
-  expr.get_loop_block ()->accept_vis (*this);
+  expr.get_cond ().accept_vis (*this);
+  expr.get_loop_block ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (IfExpr &expr)
 {
-  expr.get_if_condition ()->accept_vis (*this);
-  expr.get_if_block ()->accept_vis (*this);
+  expr.get_if_condition ().accept_vis (*this);
+  expr.get_if_block ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (IfExprConseqElse &expr)
 {
-  expr.get_if_condition ()->accept_vis (*this);
-  expr.get_if_block ()->accept_vis (*this);
-  expr.get_else_block ()->accept_vis (*this);
+  expr.get_if_condition ().accept_vis (*this);
+  expr.get_if_block ().accept_vis (*this);
+  expr.get_else_block ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (MatchExpr &expr)
 {
-  expr.get_scrutinee_expr ()->accept_vis (*this);
+  expr.get_scrutinee_expr ().accept_vis (*this);
 
   for (auto &match_arm : expr.get_match_cases ())
-    match_arm.get_expr ()->accept_vis (*this);
+    match_arm.get_expr ().accept_vis (*this);
 
   // match expressions are only an entrypoint
   TyTy::BaseType *scrutinee_ty;
   bool ok = tyctx.lookup_type (
-    expr.get_scrutinee_expr ()->get_mappings ().get_hirid (), &scrutinee_ty);
+    expr.get_scrutinee_expr ().get_mappings ().get_hirid (), &scrutinee_ty);
   rust_assert (ok);
 
   check_match_usefulness (&tyctx, scrutinee_ty, expr);
@@ -468,7 +468,7 @@ PatternChecker::visit (UseDeclaration &)
 void
 PatternChecker::visit (Function &function)
 {
-  function.get_definition ()->accept_vis (*this);
+  function.get_definition ().accept_vis (*this);
 }
 
 void
@@ -510,27 +510,27 @@ PatternChecker::visit (Union &)
 void
 PatternChecker::visit (ConstantItem &const_item)
 {
-  const_item.get_expr ()->accept_vis (*this);
+  const_item.get_expr ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (StaticItem &static_item)
 {
-  static_item.get_expr ()->accept_vis (*this);
+  static_item.get_expr ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (TraitItemFunc &item)
 {
   if (item.has_block_defined ())
-    item.get_block_expr ()->accept_vis (*this);
+    item.get_block_expr ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (TraitItemConst &item)
 {
   if (item.has_expr ())
-    item.get_expr ()->accept_vis (*this);
+    item.get_expr ().accept_vis (*this);
 }
 
 void
@@ -659,13 +659,13 @@ void
 PatternChecker::visit (LetStmt &stmt)
 {
   if (stmt.has_init_expr ())
-    stmt.get_init_expr ()->accept_vis (*this);
+    stmt.get_init_expr ().accept_vis (*this);
 }
 
 void
 PatternChecker::visit (ExprStmt &stmt)
 {
-  stmt.get_expr ()->accept_vis (*this);
+  stmt.get_expr ().accept_vis (*this);
 }
 
 void
@@ -1161,33 +1161,34 @@ WitnessMatrix::extend (const WitnessMatrix &other)
 
 // forward declarations
 static DeconstructedPat
-lower_pattern (Resolver::TypeCheckContext *ctx, HIR::Pattern *pattern,
+lower_pattern (Resolver::TypeCheckContext *ctx, HIR::Pattern &pattern,
 	       TyTy::BaseType *scrutinee_ty);
 
 static DeconstructedPat
 lower_tuple_pattern (Resolver::TypeCheckContext *ctx,
-		     HIR::TupleStructPattern *pattern,
+		     HIR::TupleStructPattern &pattern,
 		     TyTy::VariantDef *variant, Constructor &ctor)
 {
   int arity = variant->get_fields ().size ();
-  HIR::TupleStructItems *elems = pattern->get_items ().get ();
+  HIR::TupleStructItems &elems = pattern.get_items ();
 
   std::vector<DeconstructedPat> fields;
-  switch (elems->get_item_type ())
+  switch (elems.get_item_type ())
     {
       case HIR::TupleStructItems::ItemType::MULTIPLE: {
-	HIR::TupleStructItemsNoRange *multiple
-	  = static_cast<HIR::TupleStructItemsNoRange *> (elems);
+	HIR::TupleStructItemsNoRange &multiple
+	  = static_cast<HIR::TupleStructItemsNoRange &> (elems);
 
 	rust_assert (variant->get_fields ().size ()
-		     == multiple->get_patterns ().size ());
-	for (size_t i = 0; i < multiple->get_patterns ().size (); i++)
+		     == multiple.get_patterns ().size ());
+
+	for (size_t i = 0; i < multiple.get_patterns ().size (); i++)
 	  {
 	    fields.push_back (
-	      lower_pattern (ctx, multiple->get_patterns ().at (i).get (),
+	      lower_pattern (ctx, *multiple.get_patterns ().at (i),
 			     variant->get_fields ().at (i)->get_field_type ()));
 	  }
-	return DeconstructedPat (ctor, arity, fields, pattern->get_locus ());
+	return DeconstructedPat (ctor, arity, fields, pattern.get_locus ());
       }
       break;
       case HIR::TupleStructItems::ItemType::RANGED: {
@@ -1203,7 +1204,7 @@ lower_tuple_pattern (Resolver::TypeCheckContext *ctx,
 
 static DeconstructedPat
 lower_struct_pattern (Resolver::TypeCheckContext *ctx,
-		      HIR::StructPattern *pattern, TyTy::VariantDef *variant,
+		      HIR::StructPattern &pattern, TyTy::VariantDef *variant,
 		      Constructor ctor)
 {
   int arity = variant->get_fields ().size ();
@@ -1211,7 +1212,7 @@ lower_struct_pattern (Resolver::TypeCheckContext *ctx,
   // Initialize all field patterns to wildcard.
   std::vector<DeconstructedPat> fields
     = std::vector<DeconstructedPat> (arity, DeconstructedPat::make_wildcard (
-					      pattern->get_locus ()));
+					      pattern.get_locus ()));
 
   std::map<std::string, int> field_map;
   for (int i = 0; i < arity; i++)
@@ -1221,7 +1222,7 @@ lower_struct_pattern (Resolver::TypeCheckContext *ctx,
     }
 
   // Fill in the fields with the present patterns.
-  HIR::StructPatternElements elems = pattern->get_struct_pattern_elems ();
+  HIR::StructPatternElements elems = pattern.get_struct_pattern_elems ();
   for (auto &elem : elems.get_struct_pattern_fields ())
     {
       switch (elem->get_item_type ())
@@ -1232,7 +1233,7 @@ lower_struct_pattern (Resolver::TypeCheckContext *ctx,
 	    int field_idx
 	      = field_map.at (ident->get_identifier ().as_string ());
 	    fields.at (field_idx)
-	      = DeconstructedPat::make_wildcard (pattern->get_locus ());
+	      = DeconstructedPat::make_wildcard (pattern.get_locus ());
 	  }
 	  break;
 	  case HIR::StructPatternField::ItemType::IDENT_PAT: {
@@ -1241,7 +1242,7 @@ lower_struct_pattern (Resolver::TypeCheckContext *ctx,
 	    int field_idx
 	      = field_map.at (ident_pat->get_identifier ().as_string ());
 	    fields.at (field_idx) = lower_pattern (
-	      ctx, ident_pat->get_pattern ().get (),
+	      ctx, ident_pat->get_pattern (),
 	      variant->get_fields ().at (field_idx)->get_field_type ());
 	  }
 	  break;
@@ -1256,19 +1257,19 @@ lower_struct_pattern (Resolver::TypeCheckContext *ctx,
 	}
     }
 
-  return DeconstructedPat{ctor, arity, fields, pattern->get_locus ()};
+  return DeconstructedPat{ctor, arity, fields, pattern.get_locus ()};
 };
 
 static DeconstructedPat
-lower_pattern (Resolver::TypeCheckContext *ctx, HIR::Pattern *pattern,
+lower_pattern (Resolver::TypeCheckContext *ctx, HIR::Pattern &pattern,
 	       TyTy::BaseType *scrutinee_ty)
 {
-  HIR::Pattern::PatternType pat_type = pattern->get_pattern_type ();
+  HIR::Pattern::PatternType pat_type = pattern.get_pattern_type ();
   switch (pat_type)
     {
     case HIR::Pattern::PatternType::WILDCARD:
       case HIR::Pattern::PatternType::IDENTIFIER: {
-	return DeconstructedPat::make_wildcard (pattern->get_locus ());
+	return DeconstructedPat::make_wildcard (pattern.get_locus ());
       }
       break;
       case HIR::Pattern::PatternType::PATH: {
@@ -1276,12 +1277,12 @@ lower_pattern (Resolver::TypeCheckContext *ctx, HIR::Pattern *pattern,
 	// structs
 	// https://doc.rust-lang.org/reference/patterns.html#path-patterns
 	// unimplemented. Treat this pattern as wildcard for now.
-	return DeconstructedPat::make_wildcard (pattern->get_locus ());
+	return DeconstructedPat::make_wildcard (pattern.get_locus ());
       }
       break;
       case HIR::Pattern::PatternType::REFERENCE: {
 	// TODO: unimplemented. Treat this pattern as wildcard for now.
-	return DeconstructedPat::make_wildcard (pattern->get_locus ());
+	return DeconstructedPat::make_wildcard (pattern.get_locus ());
       }
       break;
     case HIR::Pattern::PatternType::STRUCT:
@@ -1289,15 +1290,15 @@ lower_pattern (Resolver::TypeCheckContext *ctx, HIR::Pattern *pattern,
 	HirId path_id = UNKNOWN_HIRID;
 	if (pat_type == HIR::Pattern::PatternType::STRUCT)
 	  {
-	    HIR::StructPattern *struct_pattern
-	      = static_cast<HIR::StructPattern *> (pattern);
-	    path_id = struct_pattern->get_path ().get_mappings ().get_hirid ();
+	    HIR::StructPattern &struct_pattern
+	      = static_cast<HIR::StructPattern &> (pattern);
+	    path_id = struct_pattern.get_path ().get_mappings ().get_hirid ();
 	  }
 	else
 	  {
-	    HIR::TupleStructPattern *tuple_pattern
-	      = static_cast<HIR::TupleStructPattern *> (pattern);
-	    path_id = tuple_pattern->get_path ().get_mappings ().get_hirid ();
+	    HIR::TupleStructPattern &tuple_pattern
+	      = static_cast<HIR::TupleStructPattern &> (pattern);
+	    path_id = tuple_pattern.get_path ().get_mappings ().get_hirid ();
 	  }
 
 	rust_assert (scrutinee_ty->get_kind () == TyTy::TypeKind::ADT);
@@ -1330,46 +1331,46 @@ lower_pattern (Resolver::TypeCheckContext *ctx, HIR::Pattern *pattern,
 
 	if (pat_type == HIR::Pattern::PatternType::STRUCT)
 	  {
-	    HIR::StructPattern *struct_pattern
-	      = static_cast<HIR::StructPattern *> (pattern);
+	    HIR::StructPattern &struct_pattern
+	      = static_cast<HIR::StructPattern &> (pattern);
 	    return lower_struct_pattern (ctx, struct_pattern, variant, ctor);
 	  }
 	else
 	  {
-	    HIR::TupleStructPattern *tuple_pattern
-	      = static_cast<HIR::TupleStructPattern *> (pattern);
+	    HIR::TupleStructPattern &tuple_pattern
+	      = static_cast<HIR::TupleStructPattern &> (pattern);
 	    return lower_tuple_pattern (ctx, tuple_pattern, variant, ctor);
 	  }
       }
       break;
       case HIR::Pattern::PatternType::TUPLE: {
 	// TODO: unimplemented. Treat this pattern as wildcard for now.
-	return DeconstructedPat::make_wildcard (pattern->get_locus ());
+	return DeconstructedPat::make_wildcard (pattern.get_locus ());
       }
       break;
       case HIR::Pattern::PatternType::SLICE: {
 	// TODO: unimplemented. Treat this pattern as wildcard for now.
-	return DeconstructedPat::make_wildcard (pattern->get_locus ());
+	return DeconstructedPat::make_wildcard (pattern.get_locus ());
       }
       break;
       case HIR::Pattern::PatternType::ALT: {
 	// TODO: unimplemented. Treat this pattern as wildcard for now.
-	return DeconstructedPat::make_wildcard (pattern->get_locus ());
+	return DeconstructedPat::make_wildcard (pattern.get_locus ());
       }
       break;
       case HIR::Pattern::PatternType::LITERAL: {
 	// TODO: unimplemented. Treat this pattern as wildcard for now.
-	return DeconstructedPat::make_wildcard (pattern->get_locus ());
+	return DeconstructedPat::make_wildcard (pattern.get_locus ());
       }
       break;
       case HIR::Pattern::PatternType::RANGE: {
 	// TODO: unimplemented. Treat this pattern as wildcard for now.
-	return DeconstructedPat::make_wildcard (pattern->get_locus ());
+	return DeconstructedPat::make_wildcard (pattern.get_locus ());
       }
       break;
       case HIR::Pattern::PatternType::GROUPED: {
 	// TODO: unimplemented. Treat this pattern as wildcard for now.
-	return DeconstructedPat::make_wildcard (pattern->get_locus ());
+	return DeconstructedPat::make_wildcard (pattern.get_locus ());
       }
       break;
       default: {
@@ -1385,8 +1386,7 @@ lower_arm (Resolver::TypeCheckContext *ctx, HIR::MatchCase &arm,
   rust_assert (arm.get_arm ().get_patterns ().size () > 0);
 
   DeconstructedPat pat
-    = lower_pattern (ctx, arm.get_arm ().get_patterns ().at (0).get (),
-		     scrutinee_ty);
+    = lower_pattern (ctx, *arm.get_arm ().get_patterns ().at (0), scrutinee_ty);
   return MatchArm (pat, arm.get_arm ().has_match_arm_guard ());
 }
 
@@ -1495,8 +1495,9 @@ emit_exhaustiveness_error (Resolver::TypeCheckContext *ctx,
 			   HIR::MatchExpr &expr, WitnessMatrix &witness)
 {
   TyTy::BaseType *scrutinee_ty;
-  bool ok = ctx->lookup_type (
-    expr.get_scrutinee_expr ()->get_mappings ().get_hirid (), &scrutinee_ty);
+  bool ok
+    = ctx->lookup_type (expr.get_scrutinee_expr ().get_mappings ().get_hirid (),
+			&scrutinee_ty);
   rust_assert (ok);
 
   if (!witness.empty ())
@@ -1514,7 +1515,7 @@ emit_exhaustiveness_error (Resolver::TypeCheckContext *ctx,
 	  if (i != witness.get_stacks ().size () - 1)
 	    buf << " and ";
 	}
-      rust_error_at (expr.get_scrutinee_expr ()->get_locus (),
+      rust_error_at (expr.get_scrutinee_expr ().get_locus (),
 		     "non-exhaustive patterns: %s not covered",
 		     buf.str ().c_str ());
     }
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc b/gcc/rust/checks/errors/rust-unsafe-checker.cc
index ee6654b4dd25..8f97edb6df5b 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.cc
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc
@@ -279,14 +279,14 @@ UnsafeChecker::visit (LiteralExpr &)
 void
 UnsafeChecker::visit (BorrowExpr &expr)
 {
-  expr.get_expr ()->accept_vis (*this);
+  expr.get_expr ().accept_vis (*this);
 }
 
 void
 UnsafeChecker::visit (DereferenceExpr &expr)
 {
   TyTy::BaseType *to_deref_type;
-  auto to_deref = expr.get_expr ()->get_mappings ().get_hirid ();
+  auto to_deref = expr.get_expr ().get_mappings ().get_hirid ();
 
   rust_assert (context.lookup_type (to_deref, &to_deref_type));
 
@@ -299,60 +299,60 @@ UnsafeChecker::visit (DereferenceExpr &expr)
 void
 UnsafeChecker::visit (ErrorPropagationExpr &expr)
 {
-  expr.get_expr ()->accept_vis (*this);
+  expr.get_expr ().accept_vis (*this);
 }
 
 void
 UnsafeChecker::visit (NegationExpr &expr)
 {
-  expr.get_expr ()->accept_vis (*this);
+  expr.get_expr ().accept_vis (*this);
 }
 
 void
 UnsafeChecker::visit (ArithmeticOrLogicalExpr &expr)
 {
-  expr.get_lhs ()->accept_vis (*this);
-  expr.get_rhs ()->accept_vis (*this);
+  expr.get_lhs ().accept_vis (*this);
+  expr.get_rhs ().accept_vis (*this);
 }
 
 void
 UnsafeChecker::visit (ComparisonExpr &expr)
 {
-  expr.get_lhs ()->accept_vis (*this);
-  expr.get_rhs ()->accept_vis (*this);
+  expr.get_lhs ().accept_vis (*this);
+  expr.get_rhs ().accept_vis (*this);
 }
 
 void
 UnsafeChecker::visit (LazyBooleanExpr &expr)
 {
-  expr.get_lhs ()->accept_vis (*this);
-  expr.get_rhs ()->accept_vis (*this);
+  expr.get_lhs ().accept_vis (*this);
+  expr.get_rhs ().accept_vis (*this);
 }
 
 void
 UnsafeChecker::visit (TypeCastExpr &expr)
 {
-  expr.get_expr ()->accept_vis (*this);
+  expr.get_expr ().accept_vis (*this);
 }
 
 void
 UnsafeChecker::visit (AssignmentExpr &expr)
 {
-  expr.get_lhs ()->accept_vis (*this);
-  expr.get_rhs ()->accept_vis (*this);
+  expr.get_lhs ().accept_vis (*this);
+  expr.get_rhs ().accept_vis (*this);
 }
 
 void
 UnsafeChecker::visit (CompoundAssignmentExpr &expr)
 {
-  expr.get_lhs ()->accept_vis (*this);
-  expr.get_rhs ()->accept_vis (*this);
+  expr.get_lhs ().accept_vis (*this);
+  expr.get_rhs ().accept_vis (*this);
 }
 
 void
 UnsafeChecker::visit (GroupedExpr &expr)
 {
-  expr.get_expr_in_parens ()->accept_vis (*this);
+  expr.get_expr_in_parens ().accept_vis (*this);
 }
 
 void
@@ -365,20 +365,20 @@ UnsafeChecker::visit (ArrayElemsValues &elems)
 void
 UnsafeChecker::visit (ArrayElemsCopied &elems)
 {
-  elems.get_elem_to_copy ()->accept_vis (*this);
+  elems.get_elem_to_copy ().accept_vis (*this);
 }
 
 void
 UnsafeChecker::visit (ArrayExpr &expr)
 {
-  expr.get_internal_elements ()->accept_vis (*this);
+  expr.get_internal_elements ().accept_vis (*this);
 }
 
 void
 UnsafeChecker::visit (ArrayIndexExpr &expr)
 {
-  expr.get_array_expr ()->accept_vis (*this);
-  expr.get_index_expr ()->accept_vis (*this);
+  expr.get_array_expr ().accept_vis (*this);
+  expr.get_index_expr ().accept_vis (*this);
 }
 
 void
@@ -391,7 +391,7 @@ UnsafeChecker::visit (TupleExpr &expr)
 void
 UnsafeChecker::visit (TupleIndexExpr &expr)
 {
-  expr.get_tuple_expr ()->accept_vis (*this);
+  expr.get_tuple_expr ().accept_vis (*this);
 }
 
 void
@@ -405,13 +405,13 @@ UnsafeChecker::visit (StructExprFieldIdentifier &)
 void
 UnsafeChecker::visit (StructExprFieldIdentifierValue &field)
 {
-  field.get_value ()->accept_vis (*this);
+  field.get_value ().accept_vis (*this);
 }
 
 void
 UnsafeChecker::visit (StructExprFieldIndexValue &field)
 {
-  field.get_value ()->accept_vis (*this);
+  field.get_value ().accept_vis (*this);
 }
 
 void
@@ -428,10 +428,10 @@ UnsafeChecker::visit (StructExprStructBase &)
 void
 UnsafeChecker::visit (CallExpr &expr)
 {
-  if (!expr.get_fnexpr ())
+  if (!expr.has_fnexpr ())
     return;
 
-  NodeId ast_node_id = expr.get_fnexpr ()->get_mappings ().get_nodeid ();
+  NodeId ast_node_id = expr.get_fnexpr ().get_mappings ().get_nodeid ();
   NodeId ref_node_id;
 
   // There are no unsafe types, and functions are defined in the name resolver.
@@ -489,7 +489,7 @@ UnsafeChecker::visit (MethodCallExpr &expr)
     check_unsafe_call (static_cast<Function *> (method->first),
 		       expr.get_locus (), "method");
 
-  expr.get_receiver ()->accept_vis (*this);
+  expr.get_receiver ().accept_vis (*this);
 
   for (auto &arg : expr.get_arguments ())
     arg->accept_vis (*this);
@@ -498,14 +498,14 @@ UnsafeChecker::visit (MethodCallExpr &expr)
 void
 UnsafeChecker::visit (FieldAccessExpr &expr)
 {
-  expr.get_receiver_expr ()->accept_vis (*this);
+  expr.get_receiver_expr ().accept_vis (*this);
 
   if (unsafe_context.is_in_context ())
     return;
 
   TyTy::BaseType *receiver_ty;
   auto ok = context.lookup_type (
-    expr.get_receiver_expr ()->get_mappings ().get_hirid (), &receiver_ty);
+    expr.get_receiver_expr ().get_mappings ().get_hirid (), &receiver_ty);
   rust_assert (ok);
 
   if (receiver_ty->get_kind () == TyTy::TypeKind::ADT)
@@ -521,7 +521,7 @@ UnsafeChecker::visit (FieldAccessExpr &expr)
 void
 UnsafeChecker::visit (ClosureExpr &expr)
 {
-  expr.get_expr ()->accept_vis (*this);
+  expr.get_expr ().accept_vis (*this);
 }
 
 void
@@ -531,7 +531,7 @@ UnsafeChecker::visit (BlockExpr &expr)
     stmt->accept_vis (*this);
 
   if (expr.has_expr ())
-    expr.get_final_expr ()->accept_vis (*this);
+    expr.get_final_expr ().accept_vis (*this);
 }
 
 void
@@ -542,26 +542,26 @@ void
 UnsafeChecker::visit (BreakExpr &expr)
 {
   if (expr.has_break_expr ())
-    expr.get_expr ()->accept_vis (*this);
+    expr.get_expr ().accept_vis (*this);
 }
 
 void
 UnsafeChecker::visit (RangeFromToExpr &expr)
 {
-  expr.get_from_expr ()->accept_vis (*this);
-  expr.get_to_expr ()->accept_vis (*this);
+  expr.get_from_expr ().accept_vis (*this);
+  expr.get_to_expr ().accept_vis (*this);
 }
 
 void
 UnsafeChecker::visit (RangeFromExpr &expr)
 {
-  expr.get_from_expr ()->accept_vis (*this);
+  expr.get_from_expr ().accept_vis (*this);
 }
 
 void
 UnsafeChecker::visit (RangeToExpr &expr)
 {
-  expr.get_to_expr ()->accept_vis (*this);
+  expr.get_to_expr ().accept_vis (*this);
 }
 
 void
@@ -571,21 +571,21 @@ UnsafeChecker::visit (RangeFullExpr &)
 void
 UnsafeChecker::visit (RangeFromToInclExpr &expr)
 {
-  expr.get_from_expr ()->accept_vis (*this);
-  expr.get_to_expr ()->accept_vis (*this);
+  expr.get_from_expr ().accept_vis (*this);
+  expr.get_to_expr ().accept_vis (*this);
 }
 
 void
 UnsafeChecker::visit (RangeToInclExpr &expr)
 {
-  expr.get_to_expr ()->accept_vis (*this);
+  expr.get_to_expr ().accept_vis (*this);
 }
 
 void
 UnsafeChecker::visit (ReturnExpr &expr)
 {
   if (expr.has_return_expr ())
-    expr.get_expr ()->accept_vis (*this);
+    expr.get_expr ().accept_vis (*this);
 }
 
 void
@@ -593,7 +593,7 @@ UnsafeChecker::visit (UnsafeBlockExpr &expr)
 {
   unsafe_context.enter (expr.get_mappings ().get_hirid ());
 
-  expr.get_block_expr ()->accept_vis (*this);
+  expr.get_block_expr ().accept_vis (*this);
 
   unsafe_context.exit ();
 }
@@ -601,45 +601,45 @@ UnsafeChecker::visit (UnsafeBlockExpr &expr)
 void
 UnsafeChecker::visit (LoopExpr &expr)
 {
-  expr.get_loop_block ()->accept_vis (*this);
+  expr.get_loop_block ().accept_vis (*this);
 }
 
 void
 UnsafeChecker::visit (WhileLoopExpr &expr)
 {
-  expr.get_predicate_expr ()->accept_vis (*this);
-  expr.get_loop_block ()->accept_vis (*this);
+  expr.get_predicate_expr ().accept_vis (*this);
+  expr.get_loop_block ().accept_vis (*this);
 }
 
 void
 UnsafeChecker::visit (WhileLetLoopExpr &expr)
 {
-  expr.get_cond ()->accept_vis (*this);
-  expr.get_loop_block ()->accept_vis (*this);
+  expr.get_cond ().accept_vis (*this);
+  expr.get_loop_block ().accept_vis (*this);
 }
 
 void
 UnsafeChecker::visit (IfExpr &expr)
 {
-  expr.get_if_condition ()->accept_vis (*this);
-  expr.get_if_block ()->accept_vis (*this);
+  expr.get_if_condition ().accept_vis (*this);
+  expr.get_if_block ().accept_vis (*this);
 }
 
 void
 UnsafeChecker::visit (IfExprConseqElse &expr)
 {
-  expr.get_if_condition ()->accept_vis (*this);
-  expr.get_if_block ()->accept_vis (*this);
-  expr.get_else_block ()->accept_vis (*this);
+  expr.get_if_condition ().accept_vis (*this);
+  expr.get_if_block ().accept_vis (*this);
+  expr.get_else_block ().accept_vis (*this);
 }
 
 void
 UnsafeChecker::visit (MatchExpr &expr)
 {
-  expr.get_scrutinee_expr ()->accept_vis (*this);
+  expr.get_scrutinee_expr ().accept_vis (*this);
 
   for (auto &match_arm : expr.get_match_cases ())
-    match_arm.get_expr ()->accept_vis (*this);
+    match_arm.get_expr ().accept_vis (*this);
 }
 
 void
@@ -716,7 +716,7 @@ UnsafeChecker::visit (Function &function)
   if (is_unsafe_fn)
     unsafe_context.enter (function.get_mappings ().get_hirid ());
 
-  function.get_definition ()->accept_vis (*this);
+  function.get_definition ().accept_vis (*this);
 
   if (is_unsafe_fn)
     unsafe_context.exit ();
@@ -764,27 +764,27 @@ UnsafeChecker::visit (Union &)
 void
 UnsafeChecker::visit (ConstantItem &const_item)
 {
-  const_item.get_expr ()->accept_vis (*this);
+  const_item.get_expr ().accept_vis (*this);
 }
 
 void
 UnsafeChecker::visit (StaticItem &static_item)
 {
-  static_item.get_expr ()->accept_vis (*this);
+  static_item.get_expr ().accept_vis (*this);
 }
 
 void
 UnsafeChecker::visit (TraitItemFunc &item)
 {
   if (item.has_block_defined ())
-    item.get_block_expr ()->accept_vis (*this);
+    item.get_block_expr ().accept_vis (*this);
 }
 
 void
 UnsafeChecker::visit (TraitItemConst &item)
 {
   if (item.has_expr ())
-    item.get_expr ()->accept_vis (*this);
+    item.get_expr ().accept_vis (*this);
 }
 
 void
@@ -931,13 +931,13 @@ void
 UnsafeChecker::visit (LetStmt &stmt)
 {
   if (stmt.has_init_expr ())
-    stmt.get_init_expr ()->accept_vis (*this);
+    stmt.get_init_expr ().accept_vis (*this);
 }
 
 void
 UnsafeChecker::visit (ExprStmt &stmt)
 {
-  stmt.get_expr ()->accept_vis (*this);
+  stmt.get_expr ().accept_vis (*this);
 }
 
 void
diff --git a/gcc/rust/checks/lints/rust-lint-marklive.cc b/gcc/rust/checks/lints/rust-lint-marklive.cc
index ca26a6690039..4b524d710c95 100644
--- a/gcc/rust/checks/lints/rust-lint-marklive.cc
+++ b/gcc/rust/checks/lints/rust-lint-marklive.cc
@@ -124,7 +124,7 @@ MarkLive::visit (HIR::PathInExpression &expr)
 void
 MarkLive::visit (HIR::MethodCallExpr &expr)
 {
-  expr.get_receiver ()->accept_vis (*this);
+  expr.get_receiver ().accept_vis (*this);
   visit_path_segment (expr.get_method_name ());
   for (auto &argument : expr.get_arguments ())
     argument->accept_vis (*this);
@@ -182,14 +182,14 @@ void
 MarkLive::visit (HIR::FieldAccessExpr &expr)
 {
   // visit receiver at first
-  expr.get_receiver_expr ()->accept_vis (*this);
+  expr.get_receiver_expr ().accept_vis (*this);
 
   // resolve the receiver back to ADT type
   TyTy::BaseType *receiver = nullptr;
   if (!tyctx->lookup_type (
-	expr.get_receiver_expr ()->get_mappings ().get_hirid (), &receiver))
+	expr.get_receiver_expr ().get_mappings ().get_hirid (), &receiver))
     {
-      rust_error_at (expr.get_receiver_expr ()->get_locus (),
+      rust_error_at (expr.get_receiver_expr ().get_locus (),
 		     "unresolved type for receiver");
     }
 
@@ -221,7 +221,7 @@ MarkLive::visit (HIR::FieldAccessExpr &expr)
   rust_assert (ok);
   if (index >= variant->num_fields ())
     {
-      rust_error_at (expr.get_receiver_expr ()->get_locus (),
+      rust_error_at (expr.get_receiver_expr ().get_locus (),
 		     "cannot access struct %s by index: %lu",
 		     adt->get_name ().c_str (), (unsigned long) index);
       return;
@@ -236,7 +236,7 @@ void
 MarkLive::visit (HIR::TupleIndexExpr &expr)
 {
   // TODO: unused tuple field detection
-  expr.get_tuple_expr ()->accept_vis (*this);
+  expr.get_tuple_expr ().accept_vis (*this);
 }
 
 void
@@ -249,13 +249,13 @@ MarkLive::visit (HIR::TypeAlias &alias)
 	= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
 
       if (auto id = nr_ctx.lookup (
-	    alias.get_type_aliased ()->get_mappings ().get_nodeid ()))
+	    alias.get_type_aliased ().get_mappings ().get_nodeid ()))
 	ast_node_id = *id;
     }
   else
     {
       resolver->lookup_resolved_type (
-	alias.get_type_aliased ()->get_mappings ().get_nodeid (), &ast_node_id);
+	alias.get_type_aliased ().get_mappings ().get_nodeid (), &ast_node_id);
     }
 
   if (auto hid = mappings.lookup_node_to_hir (ast_node_id))
diff --git a/gcc/rust/checks/lints/rust-lint-marklive.h b/gcc/rust/checks/lints/rust-lint-marklive.h
index 92b4502cab6c..93a5be7ed1e8 100644
--- a/gcc/rust/checks/lints/rust-lint-marklive.h
+++ b/gcc/rust/checks/lints/rust-lint-marklive.h
@@ -43,44 +43,44 @@ public:
 
   void visit (HIR::BorrowExpr &expr) override
   {
-    expr.get_expr ()->accept_vis (*this);
+    expr.get_expr ().accept_vis (*this);
   }
 
   void visit (HIR::DereferenceExpr &expr) override
   {
-    expr.get_expr ()->accept_vis (*this);
+    expr.get_expr ().accept_vis (*this);
   }
 
   void visit (HIR::NegationExpr &expr) override
   {
-    expr.get_expr ()->accept_vis (*this);
+    expr.get_expr ().accept_vis (*this);
   }
 
   void visit (HIR::LazyBooleanExpr &expr) override
   {
-    expr.get_lhs ()->accept_vis (*this);
-    expr.get_rhs ()->accept_vis (*this);
+    expr.get_lhs ().accept_vis (*this);
+    expr.get_rhs ().accept_vis (*this);
   }
 
   void visit (HIR::TypeCastExpr &expr) override
   {
-    expr.get_expr ()->accept_vis (*this);
+    expr.get_expr ().accept_vis (*this);
   }
 
   void visit (HIR::GroupedExpr &expr) override
   {
-    expr.get_expr_in_parens ()->accept_vis (*this);
+    expr.get_expr_in_parens ().accept_vis (*this);
   }
 
   void visit (HIR::ArrayExpr &expr) override
   {
-    expr.get_internal_elements ()->accept_vis (*this);
+    expr.get_internal_elements ().accept_vis (*this);
   }
 
   void visit (HIR::ArrayIndexExpr &expr) override
   {
-    expr.get_array_expr ()->accept_vis (*this);
-    expr.get_index_expr ()->accept_vis (*this);
+    expr.get_array_expr ().accept_vis (*this);
+    expr.get_index_expr ().accept_vis (*this);
   }
 
   void visit (HIR::ArrayElemsValues &expr) override
@@ -107,57 +107,57 @@ public:
       }
     if (expr.has_expr ())
       {
-	expr.get_final_expr ()->accept_vis (*this);
+	expr.get_final_expr ().accept_vis (*this);
       }
   }
 
   void visit (HIR::UnsafeBlockExpr &expr) override
   {
-    expr.get_block_expr ()->accept_vis (*this);
+    expr.get_block_expr ().accept_vis (*this);
   }
 
   void visit (HIR::LoopExpr &expr) override
   {
-    expr.get_loop_block ()->accept_vis (*this);
+    expr.get_loop_block ().accept_vis (*this);
   }
 
   void visit (HIR::BreakExpr &expr) override
   {
     if (expr.has_break_expr ())
-      expr.get_expr ()->accept_vis (*this);
+      expr.get_expr ().accept_vis (*this);
   }
 
   void visit (HIR::WhileLoopExpr &expr) override
   {
-    expr.get_loop_block ()->accept_vis (*this);
-    expr.get_predicate_expr ()->accept_vis (*this);
+    expr.get_loop_block ().accept_vis (*this);
+    expr.get_predicate_expr ().accept_vis (*this);
   }
 
   void visit (HIR::Function &function) override
   {
-    function.get_definition ()->accept_vis (*this);
+    function.get_definition ().accept_vis (*this);
   }
 
   void visit (HIR::ReturnExpr &expr) override
   {
     if (expr.has_return_expr ())
-      expr.get_expr ()->accept_vis (*this);
+      expr.get_expr ().accept_vis (*this);
   }
 
   void visit (HIR::WhileLetLoopExpr &expr) override
   {
-    expr.get_loop_block ()->accept_vis (*this);
-    expr.get_cond ()->accept_vis (*this);
+    expr.get_loop_block ().accept_vis (*this);
+    expr.get_cond ().accept_vis (*this);
   }
 
   void visit (HIR::ExprStmt &stmt) override
   {
-    stmt.get_expr ()->accept_vis (*this);
+    stmt.get_expr ().accept_vis (*this);
   }
 
   void visit (HIR::CallExpr &expr) override
   {
-    expr.get_fnexpr ()->accept_vis (*this);
+    expr.get_fnexpr ().accept_vis (*this);
     for (auto &argument : expr.get_arguments ())
       argument->accept_vis (*this);
   }
@@ -169,8 +169,8 @@ public:
   }
   void visit (HIR::ComparisonExpr &expr) override
   {
-    expr.get_lhs ()->accept_vis (*this);
-    expr.get_rhs ()->accept_vis (*this);
+    expr.get_lhs ().accept_vis (*this);
+    expr.get_rhs ().accept_vis (*this);
   }
 
   void visit (HIR::AssignmentExpr &expr) override
@@ -187,33 +187,33 @@ public:
 
   void visit (HIR::IfExpr &expr) override
   {
-    expr.get_if_condition ()->accept_vis (*this);
-    expr.get_if_block ()->accept_vis (*this);
+    expr.get_if_condition ().accept_vis (*this);
+    expr.get_if_block ().accept_vis (*this);
   }
 
   void visit (HIR::IfExprConseqElse &expr) override
   {
-    expr.get_if_condition ()->accept_vis (*this);
-    expr.get_if_block ()->accept_vis (*this);
-    expr.get_else_block ()->accept_vis (*this);
+    expr.get_if_condition ().accept_vis (*this);
+    expr.get_if_block ().accept_vis (*this);
+    expr.get_else_block ().accept_vis (*this);
   }
 
   void visit (HIR::MatchExpr &expr) override
   {
-    expr.get_scrutinee_expr ()->accept_vis (*this);
+    expr.get_scrutinee_expr ().accept_vis (*this);
     std::vector<HIR::MatchCase> &cases = expr.get_match_cases ();
     for (auto &&caz : cases)
       {
 	auto case_arm = caz.get_arm ();
 	if (case_arm.has_match_arm_guard ())
-	  case_arm.get_guard_expr ()->accept_vis (*this);
-	caz.get_expr ()->accept_vis (*this);
+	  case_arm.get_guard_expr ().accept_vis (*this);
+	caz.get_expr ().accept_vis (*this);
       }
   }
 
   void visit (HIR::TraitItemFunc &item) override
   {
-    item.get_block_expr ()->accept_vis (*this);
+    item.get_block_expr ().accept_vis (*this);
   }
 
   void visit (HIR::ImplBlock &impl) override
@@ -228,7 +228,7 @@ public:
   {
     if (stmt.has_init_expr ())
       {
-	stmt.get_init_expr ()->accept_vis (*this);
+	stmt.get_init_expr ().accept_vis (*this);
       }
   }
 
@@ -253,7 +253,7 @@ public:
 
   virtual void visit (HIR::StructExprFieldIdentifierValue &field) override
   {
-    field.get_value ()->accept_vis (*this);
+    field.get_value ().accept_vis (*this);
   }
 
   void visit (HIR::StructExprStructBase &stct) override
@@ -269,7 +269,7 @@ public:
 
   void visit (HIR::ClosureExpr &expr) override
   {
-    expr.get_expr ()->accept_vis (*this);
+    expr.get_expr ().accept_vis (*this);
   }
 
 private:
diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index 4fa028c07b8d..65799e89f6ba 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -800,7 +800,7 @@ Dump::visit (QualifiedPathInType &e)
   end_field ("path_type");
 
   begin_field ("associated_segment");
-  do_typepathsegment (*e.get_associated_segment ());
+  do_typepathsegment (e.get_associated_segment ());
   end_field ("associated_segment");
 
   visit_collection ("segments", e.get_segments ());
@@ -911,7 +911,7 @@ Dump::visit (ArithmeticOrLogicalExpr &e)
     }
   put_field ("expr_type", str);
   do_operatorexpr (e);
-  visit_field ("right_expr", *e.get_rhs ());
+  visit_field ("right_expr", e.get_rhs ());
 
   end ("ArithmeticOrLogicalExpr");
 }
@@ -946,7 +946,7 @@ Dump::visit (ComparisonExpr &e)
     }
   put_field ("expr_type", str);
   do_operatorexpr (e);
-  visit_field ("right_expr", *e.get_rhs ());
+  visit_field ("right_expr", e.get_rhs ());
   end ("ComparisonExpr");
 }
 
@@ -969,7 +969,7 @@ Dump::visit (LazyBooleanExpr &e)
     }
 
   do_operatorexpr (e);
-  visit_field ("right_expr", *e.get_rhs ());
+  visit_field ("right_expr", e.get_rhs ());
   end ("LazyBooleanExpr");
 }
 
@@ -987,7 +987,7 @@ Dump::visit (AssignmentExpr &e)
 {
   begin ("AssignmentExpr");
   do_operatorexpr (e);
-  visit_field ("right_expr", *e.get_rhs ());
+  visit_field ("right_expr", e.get_rhs ());
   end ("AssignmentExpr");
 }
 
@@ -997,7 +997,7 @@ Dump::visit (CompoundAssignmentExpr &e)
   begin ("CompoundAssignmentExpr");
 
   do_operatorexpr (e);
-  visit_field ("right_expr", *e.get_rhs ());
+  visit_field ("right_expr", e.get_rhs ());
 
   std::string str;
 
@@ -1684,7 +1684,7 @@ Dump::visit (TypeAlias &e)
   else
     put_field ("where clause", e.get_where_clause ().as_string ());
 
-  put_field ("type", e.get_type_aliased ()->as_string ());
+  put_field ("type", e.get_type_aliased ().as_string ());
 
   end ("TypeAlias");
 }
@@ -2050,7 +2050,7 @@ Dump::visit (IdentifierPattern &e)
   put_field ("mut", std::to_string (e.is_mut ()));
 
   if (e.has_pattern_to_bind ())
-    put_field ("to_bind", e.get_to_bind ()->as_string ());
+    put_field ("to_bind", e.get_to_bind ().as_string ());
   else
     put_field ("to_bind", "none");
 
@@ -2094,8 +2094,8 @@ Dump::visit (RangePattern &e)
 {
   begin ("RangePattern");
   do_mappings (e.get_mappings ());
-  put_field ("lower", e.get_lower_bound ()->as_string ());
-  put_field ("upper", e.get_upper_bound ()->as_string ());
+  put_field ("lower", e.get_lower_bound ().as_string ());
+  put_field ("upper", e.get_upper_bound ().as_string ());
   put_field ("has_ellipsis_syntax",
 	     std::to_string (e.get_has_ellipsis_syntax ()));
   end ("RangePattern");
@@ -2107,7 +2107,7 @@ Dump::visit (ReferencePattern &e)
   begin ("ReferencePattern");
   do_mappings (e.get_mappings ());
   put_field ("mut", std::to_string (e.is_mut ()));
-  put_field ("pattern", e.get_referenced_pattern ()->as_string ());
+  put_field ("pattern", e.get_referenced_pattern ().as_string ());
   end ("ReferencePattern");
 }
 
@@ -2119,7 +2119,7 @@ Dump::visit (StructPatternFieldTuplePat &e)
   auto oa = e.get_outer_attrs ();
   do_outer_attrs (oa);
   put_field ("index", std::to_string (e.get_index ()));
-  put_field ("tuple_pattern", e.get_tuple_pattern ()->as_string ());
+  put_field ("tuple_pattern", e.get_tuple_pattern ().as_string ());
   end ("StructPatternFieldTuplePat");
 }
 
@@ -2130,7 +2130,7 @@ Dump::visit (StructPatternFieldIdentPat &e)
   auto oa = e.get_outer_attrs ();
   do_outer_attrs (oa);
   put_field ("ident", e.get_identifier ().as_string ());
-  put_field ("ident_pattern", e.get_pattern ()->as_string ());
+  put_field ("ident_pattern", e.get_pattern ().as_string ());
   end ("StructPatternFieldIdentPat");
 }
 
@@ -2248,7 +2248,7 @@ Dump::visit (LetStmt &e)
   auto oa = e.get_outer_attrs ();
   do_outer_attrs (oa);
 
-  put_field ("variable_pattern", e.get_pattern ()->as_string ());
+  put_field ("variable_pattern", e.get_pattern ().as_string ());
 
   visit_field ("type", e.get_type ());
   visit_field ("init_expr", e.get_init_expr ());
@@ -2309,7 +2309,7 @@ Dump::visit (ParenthesisedType &e)
 {
   begin ("ParenthesisedType");
   do_type (e);
-  put_field ("type_in_parens", e.get_type_in_parens ()->as_string ());
+  put_field ("type_in_parens", e.get_type_in_parens ().as_string ());
   end ("ParenthesisedType");
 }
 
@@ -2345,7 +2345,7 @@ Dump::visit (RawPointerType &e)
   begin ("RawPointerType");
   do_type (e);
   put_field ("mut", Rust::enum_to_str (e.get_mut ()));
-  put_field ("type", e.get_type ()->as_string ());
+  put_field ("type", e.get_type ().as_string ());
   end ("RawPointerType");
 }
 
@@ -2356,7 +2356,7 @@ Dump::visit (ReferenceType &e)
   do_type (e);
   put_field ("lifetime", e.get_lifetime ().as_string ());
   put_field ("mut", enum_to_str (e.get_mut ()));
-  put_field ("type", e.get_base_type ()->as_string ());
+  put_field ("type", e.get_base_type ().as_string ());
   end ("ReferenceType");
 }
 
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h
index 0155e2546881..692b9b4a9acc 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -209,7 +209,7 @@ protected:
 public:
   location_t get_locus () const override final { return locus; }
 
-  std::unique_ptr<Expr> &get_expr () { return main_or_left_expr; }
+  Expr &get_expr () { return *main_or_left_expr; }
 
   ExprType get_expression_type () const override final
   {
@@ -423,8 +423,8 @@ public:
   void visit_lhs (HIRFullVisitor &vis) { main_or_left_expr->accept_vis (vis); }
   void visit_rhs (HIRFullVisitor &vis) { right_expr->accept_vis (vis); }
 
-  std::unique_ptr<Expr> &get_lhs () { return main_or_left_expr; }
-  std::unique_ptr<Expr> &get_rhs () { return right_expr; }
+  Expr &get_lhs () { return *main_or_left_expr; }
+  Expr &get_rhs () { return *right_expr; }
 
   std::string get_operator_str () const;
 
@@ -497,8 +497,8 @@ public:
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRExpressionVisitor &vis) override;
 
-  std::unique_ptr<Expr> &get_lhs () { return main_or_left_expr; }
-  std::unique_ptr<Expr> &get_rhs () { return right_expr; }
+  Expr &get_lhs () { return *main_or_left_expr; }
+  Expr &get_rhs () { return *right_expr; }
 
   ExprType get_kind () { return expr_type; }
 
@@ -571,8 +571,8 @@ public:
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRExpressionVisitor &vis) override;
 
-  std::unique_ptr<Expr> &get_lhs () { return main_or_left_expr; }
-  std::unique_ptr<Expr> &get_rhs () { return right_expr; }
+  Expr &get_lhs () { return *main_or_left_expr; }
+  Expr &get_rhs () { return *right_expr; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -633,12 +633,9 @@ public:
   void accept_vis (HIRExpressionVisitor &vis) override;
 
   // FIXME: isn't it the same as get_expr() from parent?
-  std::unique_ptr<Expr> &get_casted_expr () { return main_or_left_expr; }
+  Expr &get_casted_expr () { return *main_or_left_expr; }
 
-  std::unique_ptr<Type> &get_type_to_convert_to ()
-  {
-    return type_to_convert_to;
-  }
+  Type &get_type_to_convert_to () { return *type_to_convert_to; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -700,8 +697,8 @@ public:
   void visit_lhs (HIRFullVisitor &vis) { main_or_left_expr->accept_vis (vis); }
   void visit_rhs (HIRFullVisitor &vis) { right_expr->accept_vis (vis); }
 
-  std::unique_ptr<Expr> &get_lhs () { return main_or_left_expr; }
-  std::unique_ptr<Expr> &get_rhs () { return right_expr; }
+  Expr &get_lhs () { return *main_or_left_expr; }
+  Expr &get_rhs () { return *right_expr; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -770,9 +767,9 @@ public:
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRExpressionVisitor &vis) override;
 
-  std::unique_ptr<Expr> &get_lhs () { return main_or_left_expr; }
+  Expr &get_lhs () { return *main_or_left_expr; }
 
-  std::unique_ptr<Expr> &get_rhs () { return right_expr; }
+  Expr &get_rhs () { return *right_expr; }
 
   void visit_lhs (HIRFullVisitor &vis) { main_or_left_expr->accept_vis (vis); }
   void visit_rhs (HIRFullVisitor &vis) { right_expr->accept_vis (vis); }
@@ -834,7 +831,7 @@ public:
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRExpressionVisitor &vis) override;
 
-  std::unique_ptr<Expr> &get_expr_in_parens () { return expr_in_parens; }
+  Expr &get_expr_in_parens () { return *expr_in_parens; }
 
   ExprType get_expression_type () const override final
   {
@@ -986,9 +983,9 @@ public:
 
   void accept_vis (HIRFullVisitor &vis) override;
 
-  std::unique_ptr<Expr> &get_elem_to_copy () { return elem_to_copy; }
+  Expr &get_elem_to_copy () { return *elem_to_copy; }
 
-  std::unique_ptr<Expr> &get_num_copies_expr () { return num_copies; }
+  Expr &get_num_copies_expr () { return *num_copies; }
 
   ArrayElems::ArrayExprType get_array_expr_type () const override final
   {
@@ -1056,10 +1053,7 @@ public:
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRExpressionVisitor &vis) override;
 
-  std::unique_ptr<ArrayElems> &get_internal_elements ()
-  {
-    return internal_elements;
-  };
+  ArrayElems &get_internal_elements () { return *internal_elements; };
 
   ExprType get_expression_type () const override final
   {
@@ -1125,8 +1119,8 @@ public:
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRExpressionVisitor &vis) override;
 
-  std::unique_ptr<Expr> &get_array_expr () { return array_expr; }
-  std::unique_ptr<Expr> &get_index_expr () { return index_expr; }
+  Expr &get_array_expr () { return *array_expr; }
+  Expr &get_index_expr () { return *index_expr; }
 
   ExprType get_expression_type () const override final
   {
@@ -1279,7 +1273,7 @@ public:
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRExpressionVisitor &vis) override;
 
-  std::unique_ptr<Expr> &get_tuple_expr () { return tuple_expr; }
+  Expr &get_tuple_expr () { return *tuple_expr; }
 
   ExprType get_expression_type () const override final
   {
@@ -1524,7 +1518,7 @@ protected:
 public:
   std::string as_string () const override;
 
-  std::unique_ptr<Expr> &get_value () { return value; }
+  Expr &get_value () { return *value; }
 };
 
 // Identifier and value variant of StructExprField HIR node
@@ -1797,7 +1791,8 @@ public:
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRExpressionVisitor &vis) override;
 
-  std::unique_ptr<Expr> &get_fnexpr () { return function; }
+  bool has_fnexpr () const { return function != nullptr; }
+  Expr &get_fnexpr () { return *function; }
 
   size_t num_params () const { return params.size (); }
 
@@ -1884,7 +1879,7 @@ public:
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRExpressionVisitor &vis) override;
 
-  std::unique_ptr<Expr> &get_receiver () { return receiver; }
+  Expr &get_receiver () { return *receiver; }
 
   PathExprSegment &get_method_name () { return method_name; };
   const PathExprSegment &get_method_name () const { return method_name; };
@@ -1968,7 +1963,7 @@ public:
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRExpressionVisitor &vis) override;
 
-  std::unique_ptr<Expr> &get_receiver_expr () { return receiver; }
+  Expr &get_receiver_expr () { return *receiver; }
 
   Identifier get_field_name () const { return field; }
 
@@ -2058,9 +2053,9 @@ public:
   }
   std::vector<AST::Attribute> &get_outer_attrs () { return outer_attrs; }
 
-  std::unique_ptr<Pattern> &get_pattern () { return pattern; }
+  Pattern &get_pattern () { return *pattern; }
 
-  std::unique_ptr<Type> &get_type () { return type; }
+  Type &get_type () { return *type; }
 
   location_t get_locus () const { return locus; }
 };
@@ -2128,8 +2123,8 @@ public:
 
   bool has_return_type () const { return return_type != nullptr; }
 
-  std::unique_ptr<Type> &get_return_type () { return return_type; };
-  std::unique_ptr<Expr> &get_expr () { return expr; }
+  Type &get_return_type () { return *return_type; };
+  Expr &get_expr () { return *expr; }
 
   bool has_params () const { return !params.empty (); }
   std::vector<ClosureParam> &get_params () { return params; }
@@ -2243,7 +2238,7 @@ public:
 
   bool is_final_stmt (Stmt *stmt) { return statements.back ().get () == stmt; }
 
-  std::unique_ptr<Expr> &get_final_expr () { return expr; }
+  Expr &get_final_expr () { return *expr; }
 
   std::vector<std::unique_ptr<Stmt> > &get_statements () { return statements; }
 
@@ -2388,7 +2383,7 @@ public:
 
   Lifetime &get_label () { return label; }
 
-  std::unique_ptr<Expr> &get_expr () { return break_expr; }
+  Expr &get_expr () { return *break_expr; }
 
   ExprType get_expression_type () const override final
   {
@@ -2468,8 +2463,8 @@ public:
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRExpressionVisitor &vis) override;
 
-  std::unique_ptr<Expr> &get_from_expr () { return from; }
-  std::unique_ptr<Expr> &get_to_expr () { return to; }
+  Expr &get_from_expr () { return *from; }
+  Expr &get_to_expr () { return *to; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -2522,7 +2517,7 @@ public:
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRExpressionVisitor &vis) override;
 
-  std::unique_ptr<Expr> &get_from_expr () { return from; }
+  Expr &get_from_expr () { return *from; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -2576,7 +2571,7 @@ public:
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRExpressionVisitor &vis) override;
 
-  std::unique_ptr<Expr> &get_to_expr () { return to; }
+  Expr &get_to_expr () { return *to; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -2666,8 +2661,8 @@ public:
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRExpressionVisitor &vis) override;
 
-  std::unique_ptr<Expr> &get_from_expr () { return from; }
-  std::unique_ptr<Expr> &get_to_expr () { return to; }
+  Expr &get_from_expr () { return *from; }
+  Expr &get_to_expr () { return *to; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -2721,7 +2716,7 @@ public:
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRExpressionVisitor &vis) override;
 
-  std::unique_ptr<Expr> &get_to_expr () { return to; };
+  Expr &get_to_expr () { return *to; };
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -2790,7 +2785,7 @@ public:
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRExpressionVisitor &vis) override;
 
-  std::unique_ptr<Expr> &get_expr () { return return_expr; }
+  Expr &get_expr () { return *return_expr; }
 
   ExprType get_expression_type () const override final
   {
@@ -2856,7 +2851,7 @@ public:
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRExpressionVisitor &vis) override;
 
-  std::unique_ptr<BlockExpr> &get_block_expr () { return expr; }
+  BlockExpr &get_block_expr () { return *expr; }
 
   ExprType get_expression_type () const override final
   {
@@ -2932,7 +2927,7 @@ public:
 
   location_t get_locus () const override final { return locus; }
 
-  std::unique_ptr<HIR::BlockExpr> &get_loop_block () { return loop_block; };
+  HIR::BlockExpr &get_loop_block () { return *loop_block; };
 
   LoopLabel &get_loop_label () { return loop_label; }
 };
@@ -3010,7 +3005,7 @@ public:
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRExpressionVisitor &vis) override;
 
-  std::unique_ptr<Expr> &get_predicate_expr () { return condition; }
+  Expr &get_predicate_expr () { return *condition; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -3086,7 +3081,7 @@ public:
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRExpressionVisitor &vis) override;
 
-  std::unique_ptr<Expr> &get_cond () { return condition; }
+  Expr &get_cond () { return *condition; }
   std::vector<std::unique_ptr<Pattern> > &get_patterns ()
   {
     return match_arm_patterns;
@@ -3166,8 +3161,8 @@ public:
   void vis_if_condition (HIRFullVisitor &vis) { condition->accept_vis (vis); }
   void vis_if_block (HIRFullVisitor &vis) { if_block->accept_vis (vis); }
 
-  std::unique_ptr<Expr> &get_if_condition () { return condition; }
-  std::unique_ptr<BlockExpr> &get_if_block () { return if_block; }
+  Expr &get_if_condition () { return *condition; }
+  BlockExpr &get_if_block () { return *if_block; }
 
   ExprType get_expression_type () const final override { return ExprType::If; }
 
@@ -3230,7 +3225,7 @@ public:
 
   void vis_else_block (HIRFullVisitor &vis) { else_block->accept_vis (vis); }
 
-  std::unique_ptr<ExprWithBlock> &get_else_block () { return else_block; }
+  ExprWithBlock &get_else_block () { return *else_block; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -3330,7 +3325,7 @@ public:
     return match_arm_patterns;
   }
 
-  std::unique_ptr<Expr> &get_guard_expr () { return guard_expr; }
+  Expr &get_guard_expr () { return *guard_expr; }
 
   location_t get_locus () const { return locus; }
 };
@@ -3374,7 +3369,7 @@ public:
   Analysis::NodeMapping get_mappings () const { return mappings; }
 
   MatchArm &get_arm () { return arm; }
-  std::unique_ptr<Expr> &get_expr () { return expr; }
+  Expr &get_expr () { return *expr; }
 };
 
 // Match expression HIR node
@@ -3435,7 +3430,7 @@ public:
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRExpressionVisitor &vis) override;
 
-  std::unique_ptr<Expr> &get_scrutinee_expr () { return branch_value; }
+  Expr &get_scrutinee_expr () { return *branch_value; }
   AST::AttrVec get_inner_attrs () const { return inner_attrs; }
   const std::vector<MatchCase> &get_match_cases () const { return match_arms; }
   std::vector<MatchCase> &get_match_cases () { return match_arms; }
@@ -3499,7 +3494,7 @@ public:
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRExpressionVisitor &vis) override;
 
-  std::unique_ptr<Expr> &get_awaited_expr () { return awaited_expr; }
+  Expr &get_awaited_expr () { return *awaited_expr; }
 
   ExprType get_expression_type () const final override
   {
@@ -3556,7 +3551,7 @@ public:
   location_t get_locus () const override final { return locus; }
 
   bool get_has_move () const { return has_move; }
-  std::unique_ptr<BlockExpr> &get_block_expr () { return block_expr; }
+  BlockExpr &get_block_expr () { return *block_expr; }
 
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRExpressionVisitor &vis) override;
@@ -3581,31 +3576,31 @@ class OperatorExprMeta
 public:
   OperatorExprMeta (HIR::CompoundAssignmentExpr &expr)
     : node_mappings (expr.get_mappings ()),
-      lvalue_mappings (expr.get_expr ()->get_mappings ()),
+      lvalue_mappings (expr.get_expr ().get_mappings ()),
       locus (expr.get_locus ())
   {}
 
   OperatorExprMeta (HIR::ArithmeticOrLogicalExpr &expr)
     : node_mappings (expr.get_mappings ()),
-      lvalue_mappings (expr.get_expr ()->get_mappings ()),
+      lvalue_mappings (expr.get_expr ().get_mappings ()),
       locus (expr.get_locus ())
   {}
 
   OperatorExprMeta (HIR::NegationExpr &expr)
     : node_mappings (expr.get_mappings ()),
-      lvalue_mappings (expr.get_expr ()->get_mappings ()),
+      lvalue_mappings (expr.get_expr ().get_mappings ()),
       locus (expr.get_locus ())
   {}
 
   OperatorExprMeta (HIR::DereferenceExpr &expr)
     : node_mappings (expr.get_mappings ()),
-      lvalue_mappings (expr.get_expr ()->get_mappings ()),
+      lvalue_mappings (expr.get_expr ().get_mappings ()),
       locus (expr.get_locus ())
   {}
 
   OperatorExprMeta (HIR::ArrayIndexExpr &expr)
     : node_mappings (expr.get_mappings ()),
-      lvalue_mappings (expr.get_array_expr ()->get_mappings ()),
+      lvalue_mappings (expr.get_array_expr ().get_mappings ()),
       locus (expr.get_locus ())
   {}
 
diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index 1f53e853dccc..3e98ad412ed2 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -118,7 +118,7 @@ public:
 
   Identifier get_type_representation () const { return type_representation; }
 
-  std::unique_ptr<Type> &get_type () { return type; }
+  Type &get_type () { return *type; }
 
   Analysis::NodeMapping get_type_mappings () const
   {
@@ -277,7 +277,7 @@ public:
 
   std::vector<LifetimeParam> &get_for_lifetimes () { return for_lifetimes; }
 
-  std::unique_ptr<Type> &get_bound_type () { return bound_type; }
+  Type &get_bound_type () { return *bound_type; }
 
   std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ()
   {
@@ -452,7 +452,7 @@ public:
 
   ImplicitSelfKind get_self_kind () const { return self_kind; }
 
-  std::unique_ptr<Type> &get_type () { return type; }
+  Type &get_type () { return *type; }
 
   Analysis::NodeMapping get_mappings () { return mappings; }
 
@@ -547,9 +547,11 @@ public:
 
   location_t get_locus () const { return locus; }
 
-  std::unique_ptr<Pattern> &get_param_name () { return param_name; }
+  Pattern &get_param_name () { return *param_name; }
 
-  std::unique_ptr<Type> &get_type () { return type; }
+  std::unique_ptr<Pattern> take_param_name () { return std::move (param_name); }
+
+  Type &get_type () { return *type; }
 
   const Analysis::NodeMapping &get_mappings () const { return mappings; }
 };
@@ -1056,7 +1058,7 @@ public:
   location_t get_locus () const override final { return locus; }
   ItemKind get_item_kind () const override { return ItemKind::UseDeclaration; }
 
-  std::unique_ptr<UseTree> &get_use_tree () { return use_tree; }
+  UseTree &get_use_tree () { return *use_tree; }
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRStmtVisitor &vis) override;
   void accept_vis (HIRVisItemVisitor &vis) override;
@@ -1210,7 +1212,7 @@ public:
   }
 
   // TODO: is this better? Or is a "vis_block" better?
-  std::unique_ptr<BlockExpr> &get_definition () { return function_body; }
+  BlockExpr &get_definition () { return *function_body; }
 
   const FunctionQualifiers &get_qualifiers () const { return qualifiers; }
 
@@ -1222,7 +1224,7 @@ public:
   bool has_return_type () const { return return_type != nullptr; }
 
   // TODO: is this better? Or is a "vis_block" better?
-  std::unique_ptr<Type> &get_return_type () { return return_type; }
+  Type &get_return_type () { return *return_type; }
 
   bool is_method () const { return !self.is_error (); }
 
@@ -1337,7 +1339,7 @@ public:
 
   WhereClause &get_where_clause () { return where_clause; }
 
-  std::unique_ptr<Type> &get_type_aliased () { return existing_type; }
+  Type &get_type_aliased () { return *existing_type; }
 
   Identifier get_new_type_name () const { return new_type_name; }
 
@@ -1503,7 +1505,7 @@ public:
 
   Identifier get_field_name () const { return field_name; }
 
-  std::unique_ptr<Type> &get_field_type () { return field_type; }
+  Type &get_field_type () { return *field_type; }
 
   Analysis::NodeMapping get_mappings () const { return mappings; }
 
@@ -1640,7 +1642,7 @@ public:
   location_t get_locus () const { return locus; }
 
   AST::AttrVec &get_outer_attrs () { return outer_attrs; }
-  std::unique_ptr<HIR::Type> &get_field_type () { return field_type; }
+  HIR::Type &get_field_type () { return *field_type; }
 };
 
 // Rust tuple declared using struct keyword HIR node
@@ -1855,7 +1857,12 @@ public:
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRStmtVisitor &vis) override;
 
-  std::unique_ptr<Expr> &get_discriminant_expression () { return expression; }
+  Expr &get_discriminant_expression () { return *expression; }
+
+  std::unique_ptr<Expr> take_discriminant_expression ()
+  {
+    return std::move (expression);
+  }
 
 protected:
   // Clone function implementation as (not pure) virtual method
@@ -2126,9 +2133,9 @@ public:
   void accept_vis (HIRImplVisitor &vis) override;
   void accept_vis (HIRVisItemVisitor &vis) override;
 
-  std::unique_ptr<Type> &get_type () { return type; }
+  Type &get_type () { return *type; }
 
-  std::unique_ptr<Expr> &get_expr () { return const_expr; }
+  Expr &get_expr () { return *const_expr; }
 
   Identifier get_identifier () const { return identifier; }
 
@@ -2222,9 +2229,9 @@ public:
 
   bool is_mut () const { return mut == Mutability::Mut; }
 
-  std::unique_ptr<Expr> &get_expr () { return expr; }
+  Expr &get_expr () { return *expr; }
 
-  std::unique_ptr<Type> &get_type () { return type; }
+  Type &get_type () { return *type; }
 
   ItemKind get_item_kind () const override { return ItemKind::Static; }
 
@@ -2324,7 +2331,7 @@ public:
     return generic_params;
   }
 
-  std::unique_ptr<Type> &get_return_type () { return return_type; }
+  Type &get_return_type () { return *return_type; }
 
   std::vector<FunctionParam> &get_function_params () { return function_params; }
 
@@ -2391,7 +2398,7 @@ public:
 
   bool has_block_defined () const { return block_expr != nullptr; }
 
-  std::unique_ptr<BlockExpr> &get_block_expr () { return block_expr; }
+  BlockExpr &get_block_expr () { return *block_expr; }
 
   const std::string trait_identifier () const override final
   {
@@ -2476,9 +2483,9 @@ public:
 
   bool has_expr () const { return expr != nullptr; }
 
-  std::unique_ptr<Type> &get_type () { return type; }
+  Type &get_type () { return *type; }
 
-  std::unique_ptr<Expr> &get_expr () { return expr; }
+  Expr &get_expr () { return *expr; }
 
   const std::string trait_identifier () const override final
   {
@@ -2828,7 +2835,9 @@ public:
 
   location_t get_locus () const override final { return locus; }
 
-  std::unique_ptr<Type> &get_type () { return impl_type; };
+  Type &get_type () { return *impl_type; };
+
+  bool has_type () { return impl_type == nullptr; }
 
   std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
   {
@@ -2837,7 +2846,7 @@ public:
 
   bool has_trait_ref () const { return trait_ref != nullptr; }
 
-  std::unique_ptr<TypePath> &get_trait_ref () { return trait_ref; }
+  TypePath &get_trait_ref () { return *trait_ref; }
 
   WhereClause &get_where_clause () { return where_clause; }
 
@@ -2976,7 +2985,7 @@ public:
 
   Mutability get_mut () { return mut; }
 
-  std::unique_ptr<Type> &get_item_type () { return item_type; }
+  Type &get_item_type () { return *item_type; }
 
   ExternKind get_extern_kind () override { return ExternKind::Static; }
 
@@ -3033,7 +3042,7 @@ public:
 
   Identifier get_param_name () const { return name; }
 
-  std::unique_ptr<Type> &get_type () { return param_type; }
+  Type &get_type () { return *param_type; }
 
   Analysis::NodeMapping get_mappings () const { return mappings; }
 };
@@ -3132,7 +3141,7 @@ public:
     return generic_params;
   }
 
-  std::unique_ptr<Type> &get_return_type () { return return_type; }
+  Type &get_return_type () { return *return_type; }
 
   std::vector<NamedFunctionParam> &get_function_params ()
   {
diff --git a/gcc/rust/hir/tree/rust-hir-path.h b/gcc/rust/hir/tree/rust-hir-path.h
index e406d534f16b..18197837afae 100644
--- a/gcc/rust/hir/tree/rust-hir-path.h
+++ b/gcc/rust/hir/tree/rust-hir-path.h
@@ -107,8 +107,8 @@ public:
   Identifier &get_identifier () { return identifier; }
   const Identifier &get_identifier () const { return identifier; }
 
-  std::unique_ptr<Type> &get_type () { return type; }
-  const std::unique_ptr<Type> &get_type () const { return type; }
+  Type &get_type () { return *type; }
+  const Type &get_type () const { return *type; }
 
   location_t get_locus () const { return locus; }
 };
@@ -574,7 +574,7 @@ public:
   TypePathFunction (TypePathFunction const &other)
   {
     return_type = other.has_return_type ()
-		    ? other.get_return_type ()->clone_type ()
+		    ? other.get_return_type ().clone_type ()
 		    : nullptr;
 
     inputs.reserve (other.inputs.size ());
@@ -588,7 +588,7 @@ public:
   TypePathFunction &operator= (TypePathFunction const &other)
   {
     return_type = other.has_return_type ()
-		    ? other.get_return_type ()->clone_type ()
+		    ? other.get_return_type ().clone_type ()
 		    : nullptr;
 
     inputs.reserve (other.inputs.size ());
@@ -610,8 +610,8 @@ public:
   };
   std::vector<std::unique_ptr<Type> > &get_params () { return inputs; };
 
-  const std::unique_ptr<Type> &get_return_type () const { return return_type; };
-  std::unique_ptr<Type> &get_return_type () { return return_type; };
+  const Type &get_return_type () const { return *return_type; };
+  Type &get_return_type () { return *return_type; };
 };
 
 // Segment used in type path with a function argument
@@ -811,9 +811,9 @@ public:
 
   Analysis::NodeMapping get_mappings () const { return mappings; }
 
-  std::unique_ptr<Type> &get_type () { return type; }
+  Type &get_type () { return *type; }
 
-  std::unique_ptr<TypePath> &get_trait () { return trait; }
+  TypePath &get_trait () { return *trait; }
 
   bool trait_has_generic_args () const
   {
@@ -963,10 +963,7 @@ public:
 
   QualifiedPathType &get_path_type () { return path_type; }
 
-  std::unique_ptr<TypePathSegment> &get_associated_segment ()
-  {
-    return associated_segment;
-  }
+  TypePathSegment &get_associated_segment () { return *associated_segment; }
 
   std::vector<std::unique_ptr<TypePathSegment> > &get_segments ()
   {
diff --git a/gcc/rust/hir/tree/rust-hir-pattern.h b/gcc/rust/hir/tree/rust-hir-pattern.h
index e5d83716edfc..df26a3964576 100644
--- a/gcc/rust/hir/tree/rust-hir-pattern.h
+++ b/gcc/rust/hir/tree/rust-hir-pattern.h
@@ -132,7 +132,7 @@ public:
 
   bool is_mut () const { return mut == Mutability::Mut; }
   bool get_is_ref () const { return is_ref; }
-  std::unique_ptr<Pattern> &get_to_bind () { return to_bind; }
+  Pattern &get_to_bind () { return *to_bind; }
 
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRPatternVisitor &vis) override;
@@ -405,9 +405,9 @@ public:
     return PatternType::RANGE;
   }
 
-  std::unique_ptr<RangePatternBound> &get_lower_bound () { return lower; }
+  RangePatternBound &get_lower_bound () { return *lower; }
 
-  std::unique_ptr<RangePatternBound> &get_upper_bound () { return upper; }
+  RangePatternBound &get_upper_bound () { return *upper; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -476,7 +476,7 @@ public:
     return PatternType::REFERENCE;
   }
 
-  std::unique_ptr<Pattern> &get_referenced_pattern () { return pattern; }
+  Pattern &get_referenced_pattern () { return *pattern; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -572,7 +572,7 @@ public:
   void accept_vis (HIRFullVisitor &vis) override;
 
   TupleIndex get_index () { return index; }
-  std::unique_ptr<Pattern> &get_tuple_pattern () { return tuple_pattern; }
+  Pattern &get_tuple_pattern () { return *tuple_pattern; }
 
   ItemType get_item_type () const override final { return ItemType::TUPLE_PAT; }
 
@@ -630,7 +630,7 @@ public:
 
   Identifier get_identifier () const { return ident; }
 
-  std::unique_ptr<Pattern> &get_pattern () { return ident_pattern; }
+  Pattern &get_pattern () { return *ident_pattern; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -1002,7 +1002,7 @@ public:
 
   PathInExpression &get_path () { return path; }
 
-  std::unique_ptr<TupleStructItems> &get_items () { return items; }
+  TupleStructItems &get_items () { return *items; }
 
   const Analysis::NodeMapping &get_mappings () const override final
   {
@@ -1221,8 +1221,8 @@ public:
     return PatternType::TUPLE;
   }
 
-  std::unique_ptr<TuplePatternItems> &get_items () { return items; }
-  const std::unique_ptr<TuplePatternItems> &get_items () const { return items; }
+  TuplePatternItems &get_items () { return *items; }
+  const TuplePatternItems &get_items () const { return *items; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
diff --git a/gcc/rust/hir/tree/rust-hir-stmt.h b/gcc/rust/hir/tree/rust-hir-stmt.h
index e6e844fb559a..7320bb623851 100644
--- a/gcc/rust/hir/tree/rust-hir-stmt.h
+++ b/gcc/rust/hir/tree/rust-hir-stmt.h
@@ -144,11 +144,11 @@ public:
   }
   std::vector<AST::Attribute> &get_outer_attrs () { return outer_attrs; }
 
-  std::unique_ptr<HIR::Type> &get_type () { return type; }
+  HIR::Type &get_type () { return *type; }
 
-  std::unique_ptr<HIR::Expr> &get_init_expr () { return init_expr; }
+  HIR::Expr &get_init_expr () { return *init_expr; }
 
-  std::unique_ptr<HIR::Pattern> &get_pattern () { return variables_pattern; }
+  HIR::Pattern &get_pattern () { return *variables_pattern; }
 
   bool is_item () const override final { return false; }
 
@@ -186,7 +186,7 @@ public:
 
   bool is_item () const override final { return false; }
 
-  std::unique_ptr<Expr> &get_expr () { return expr; }
+  Expr &get_expr () { return *expr; }
 
   // Copy constructor with clone
   ExprStmt (ExprStmt const &other)
diff --git a/gcc/rust/hir/tree/rust-hir-type.h b/gcc/rust/hir/tree/rust-hir-type.h
index e4a97547b92a..26c3d2dfa49f 100644
--- a/gcc/rust/hir/tree/rust-hir-type.h
+++ b/gcc/rust/hir/tree/rust-hir-type.h
@@ -271,7 +271,7 @@ public:
      * parenthesised type, it must be in parentheses. */
     return type_in_parens->to_trait_bound (true);
   }
-  std::unique_ptr<Type> &get_type_in_parens () { return type_in_parens; }
+  Type &get_type_in_parens () { return *type_in_parens; }
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRTypeVisitor &vis) override;
 };
@@ -439,7 +439,7 @@ public:
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRTypeVisitor &vis) override;
 
-  std::unique_ptr<Type> &get_type () { return type; }
+  Type &get_type () { return *type; }
 
   Mutability get_mut () const { return mut; }
 
@@ -447,7 +447,7 @@ public:
 
   bool is_const () const { return mut == Mutability::Imm; }
 
-  std::unique_ptr<Type> &get_base_type () { return type; }
+  Type &get_base_type () { return *type; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -520,7 +520,7 @@ public:
 
   Mutability get_mut () const { return mut; }
 
-  std::unique_ptr<Type> &get_base_type () { return type; }
+  Type &get_base_type () { return *type; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -578,9 +578,9 @@ public:
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRTypeVisitor &vis) override;
 
-  std::unique_ptr<Type> &get_element_type () { return elem_type; }
+  Type &get_element_type () { return *elem_type; }
 
-  std::unique_ptr<Expr> &get_size_expr () { return size; }
+  Expr &get_size_expr () { return *size; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -633,7 +633,7 @@ public:
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRTypeVisitor &vis) override;
 
-  std::unique_ptr<Type> &get_element_type () { return elem_type; }
+  Type &get_element_type () { return *elem_type; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -743,7 +743,7 @@ public:
 
   location_t get_locus () const { return locus; }
 
-  std::unique_ptr<Type> &get_type () { return param_type; }
+  Type &get_type () { return *param_type; }
 
   ParamKind get_param_kind () const { return param_kind; }
 
@@ -828,7 +828,7 @@ public:
   }
 
   // TODO: would a "vis_type" be better?
-  std::unique_ptr<Type> &get_return_type () { return return_type; }
+  Type &get_return_type () { return *return_type; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
diff --git a/gcc/rust/hir/tree/rust-hir.h b/gcc/rust/hir/tree/rust-hir.h
index 8544d0d5f09d..7d133e135b09 100644
--- a/gcc/rust/hir/tree/rust-hir.h
+++ b/gcc/rust/hir/tree/rust-hir.h
@@ -765,11 +765,8 @@ public:
   bool has_default_expression () { return default_expression != nullptr; }
 
   std::string get_name () { return name; }
-  std::unique_ptr<Type> &get_type () { return type; }
-  std::unique_ptr<Expr> &get_default_expression ()
-  {
-    return default_expression;
-  }
+  Type &get_type () { return *type; }
+  Expr &get_default_expression () { return *default_expression; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
diff --git a/gcc/rust/typecheck/rust-autoderef.cc b/gcc/rust/typecheck/rust-autoderef.cc
index 7e80b8efddf3..75da3919ea4b 100644
--- a/gcc/rust/typecheck/rust-autoderef.cc
+++ b/gcc/rust/typecheck/rust-autoderef.cc
@@ -209,7 +209,7 @@ resolve_operator_overload_fn (
 	       == 0)
 	{
 	  TraitReference *trait_reference
-	    = TraitResolver::Lookup (*parent->get_trait_ref ().get ());
+	    = TraitResolver::Lookup (parent->get_trait_ref ());
 	  if (!trait_reference->is_error ())
 	    {
 	      TyTy::BaseType *lookup = nullptr;
diff --git a/gcc/rust/typecheck/rust-hir-dot-operator.cc b/gcc/rust/typecheck/rust-hir-dot-operator.cc
index 8e5473f2f2e3..6af23176467b 100644
--- a/gcc/rust/typecheck/rust-hir-dot-operator.cc
+++ b/gcc/rust/typecheck/rust-hir-dot-operator.cc
@@ -200,104 +200,103 @@ MethodResolver::select (TyTy::BaseType &receiver)
   };
 
   std::vector<trait_item_candidate> trait_fns;
-  mappings.iterate_impl_blocks (
-    [&] (HirId id, HIR::ImplBlock *impl) mutable -> bool {
-      bool is_trait_impl = impl->has_trait_ref ();
-      if (!is_trait_impl)
-	return true;
-
-      // look for impl implementation else lookup the associated trait item
-      for (auto &impl_item : impl->get_impl_items ())
-	{
-	  bool is_fn = impl_item->get_impl_item_type ()
-		       == HIR::ImplItem::ImplItemType::FUNCTION;
-	  if (!is_fn)
-	    continue;
-
-	  HIR::Function *func = static_cast<HIR::Function *> (impl_item.get ());
-	  if (!func->is_method ())
-	    continue;
-
-	  bool name_matches = func->get_function_name ().as_string ().compare (
-				segment_name.as_string ())
-			      == 0;
-	  if (!name_matches)
-	    continue;
-
-	  TyTy::BaseType *ty = nullptr;
-	  if (!query_type (func->get_mappings ().get_hirid (), &ty))
-	    continue;
-	  if (ty->get_kind () == TyTy::TypeKind::ERROR)
-	    continue;
-
-	  rust_assert (ty->get_kind () == TyTy::TypeKind::FNDEF);
-	  TyTy::FnType *fnty = static_cast<TyTy::FnType *> (ty);
-	  const TyTy::BaseType *impl_self
-	    = TypeCheckItem::ResolveImplBlockSelf (*impl);
-
-	  // see:
-	  // https://gcc-rust.zulipchat.com/#narrow/stream/266897-general/topic/Method.20Resolution/near/338646280
-	  // https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/method/probe.rs#L650-L660
-	  bool impl_self_is_ptr
-	    = impl_self->get_kind () == TyTy::TypeKind::POINTER;
-	  bool impl_self_is_ref = impl_self->get_kind () == TyTy::TypeKind::REF;
-	  if (receiver_is_raw_ptr && impl_self_is_ptr)
-	    {
-	      const TyTy::PointerType &sptr
-		= *static_cast<const TyTy::PointerType *> (impl_self);
-	      const TyTy::PointerType &ptr
-		= *static_cast<const TyTy::PointerType *> (raw);
-
-	      // we could do this via lang-item assemblies if we refactor this
-	      bool mut_match = sptr.mutability () == ptr.mutability ();
-	      if (!mut_match)
-		continue;
-	    }
-	  else if (receiver_is_ref && impl_self_is_ref)
-	    {
-	      const TyTy::ReferenceType &sptr
-		= *static_cast<const TyTy::ReferenceType *> (impl_self);
-	      const TyTy::ReferenceType &ptr
-		= *static_cast<const TyTy::ReferenceType *> (raw);
-
-	      // we could do this via lang-item assemblies if we refactor this
-	      bool mut_match = sptr.mutability () == ptr.mutability ();
-	      if (!mut_match)
-		continue;
-	    }
+  mappings.iterate_impl_blocks ([&] (HirId id,
+				     HIR::ImplBlock *impl) mutable -> bool {
+    bool is_trait_impl = impl->has_trait_ref ();
+    if (!is_trait_impl)
+      return true;
 
-	  inherent_impl_fns.push_back ({func, impl, fnty});
-	  return true;
-	}
+    // look for impl implementation else lookup the associated trait item
+    for (auto &impl_item : impl->get_impl_items ())
+      {
+	bool is_fn = impl_item->get_impl_item_type ()
+		     == HIR::ImplItem::ImplItemType::FUNCTION;
+	if (!is_fn)
+	  continue;
+
+	HIR::Function *func = static_cast<HIR::Function *> (impl_item.get ());
+	if (!func->is_method ())
+	  continue;
+
+	bool name_matches = func->get_function_name ().as_string ().compare (
+			      segment_name.as_string ())
+			    == 0;
+	if (!name_matches)
+	  continue;
+
+	TyTy::BaseType *ty = nullptr;
+	if (!query_type (func->get_mappings ().get_hirid (), &ty))
+	  continue;
+	if (ty->get_kind () == TyTy::TypeKind::ERROR)
+	  continue;
+
+	rust_assert (ty->get_kind () == TyTy::TypeKind::FNDEF);
+	TyTy::FnType *fnty = static_cast<TyTy::FnType *> (ty);
+	const TyTy::BaseType *impl_self
+	  = TypeCheckItem::ResolveImplBlockSelf (*impl);
+
+	// see:
+	// https://gcc-rust.zulipchat.com/#narrow/stream/266897-general/topic/Method.20Resolution/near/338646280
+	// https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/method/probe.rs#L650-L660
+	bool impl_self_is_ptr
+	  = impl_self->get_kind () == TyTy::TypeKind::POINTER;
+	bool impl_self_is_ref = impl_self->get_kind () == TyTy::TypeKind::REF;
+	if (receiver_is_raw_ptr && impl_self_is_ptr)
+	  {
+	    const TyTy::PointerType &sptr
+	      = *static_cast<const TyTy::PointerType *> (impl_self);
+	    const TyTy::PointerType &ptr
+	      = *static_cast<const TyTy::PointerType *> (raw);
+
+	    // we could do this via lang-item assemblies if we refactor this
+	    bool mut_match = sptr.mutability () == ptr.mutability ();
+	    if (!mut_match)
+	      continue;
+	  }
+	else if (receiver_is_ref && impl_self_is_ref)
+	  {
+	    const TyTy::ReferenceType &sptr
+	      = *static_cast<const TyTy::ReferenceType *> (impl_self);
+	    const TyTy::ReferenceType &ptr
+	      = *static_cast<const TyTy::ReferenceType *> (raw);
+
+	    // we could do this via lang-item assemblies if we refactor this
+	    bool mut_match = sptr.mutability () == ptr.mutability ();
+	    if (!mut_match)
+	      continue;
+	  }
+
+	inherent_impl_fns.push_back ({func, impl, fnty});
+	return true;
+      }
 
-      TraitReference *trait_ref
-	= TraitResolver::Resolve (*impl->get_trait_ref ().get ());
-      rust_assert (!trait_ref->is_error ());
+    TraitReference *trait_ref = TraitResolver::Resolve (impl->get_trait_ref ());
+    rust_assert (!trait_ref->is_error ());
 
-      auto item_ref
-	= trait_ref->lookup_trait_item (segment_name.as_string (),
-					TraitItemReference::TraitItemType::FN);
-      if (item_ref->is_error ())
-	return true;
+    auto item_ref
+      = trait_ref->lookup_trait_item (segment_name.as_string (),
+				      TraitItemReference::TraitItemType::FN);
+    if (item_ref->is_error ())
+      return true;
 
-      const HIR::Trait *trait = trait_ref->get_hir_trait_ref ();
-      HIR::TraitItem *item = item_ref->get_hir_trait_item ();
-      if (item->get_item_kind () != HIR::TraitItem::TraitItemKind::FUNC)
-	return true;
+    const HIR::Trait *trait = trait_ref->get_hir_trait_ref ();
+    HIR::TraitItem *item = item_ref->get_hir_trait_item ();
+    if (item->get_item_kind () != HIR::TraitItem::TraitItemKind::FUNC)
+      return true;
 
-      HIR::TraitItemFunc *func = static_cast<HIR::TraitItemFunc *> (item);
-      if (!func->get_decl ().is_method ())
-	return true;
+    HIR::TraitItemFunc *func = static_cast<HIR::TraitItemFunc *> (item);
+    if (!func->get_decl ().is_method ())
+      return true;
 
-      TyTy::BaseType *ty = item_ref->get_tyty ();
-      rust_assert (ty->get_kind () == TyTy::TypeKind::FNDEF);
-      TyTy::FnType *fnty = static_cast<TyTy::FnType *> (ty);
+    TyTy::BaseType *ty = item_ref->get_tyty ();
+    rust_assert (ty->get_kind () == TyTy::TypeKind::FNDEF);
+    TyTy::FnType *fnty = static_cast<TyTy::FnType *> (ty);
 
-      trait_item_candidate candidate{func, trait, fnty, trait_ref, item_ref};
-      trait_fns.push_back (candidate);
+    trait_item_candidate candidate{func, trait, fnty, trait_ref, item_ref};
+    trait_fns.push_back (candidate);
 
-      return true;
-    });
+    return true;
+  });
 
   // lookup specified bounds for an associated item
   struct precdicate_candidate
diff --git a/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h b/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h
index 5cef1c268a48..5537b14fbb26 100644
--- a/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h
+++ b/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h
@@ -54,7 +54,7 @@ public:
     //   impl-type -> [ (item, name), ... ]
     // }
 
-    HirId impl_type_id = impl->get_type ()->get_mappings ().get_hirid ();
+    HirId impl_type_id = impl->get_type ().get_mappings ().get_hirid ();
     TyTy::BaseType *impl_type = nullptr;
     bool ok = query_type (impl_type_id, &impl_type);
     if (!ok)
diff --git a/gcc/rust/typecheck/rust-hir-path-probe.cc b/gcc/rust/typecheck/rust-hir-path-probe.cc
index 196cc825e0a0..2e9ad95dde3d 100644
--- a/gcc/rust/typecheck/rust-hir-path-probe.cc
+++ b/gcc/rust/typecheck/rust-hir-path-probe.cc
@@ -297,7 +297,7 @@ PathProbeType::process_impl_item_candidate (HirId id, HIR::ImplItem *item,
 					    HIR::ImplBlock *impl)
 {
   current_impl = impl;
-  HirId impl_ty_id = impl->get_type ()->get_mappings ().get_hirid ();
+  HirId impl_ty_id = impl->get_type ().get_mappings ().get_hirid ();
   TyTy::BaseType *impl_block_ty = nullptr;
   if (!query_type (impl_ty_id, &impl_block_ty))
     return;
@@ -472,8 +472,7 @@ PathProbeImplTrait::process_trait_impl_items_for_candidates ()
       if (!impl->has_trait_ref ())
 	return true;
 
-      TraitReference *resolved
-	= TraitResolver::Lookup (*(impl->get_trait_ref ().get ()));
+      TraitReference *resolved = TraitResolver::Lookup (impl->get_trait_ref ());
       if (!trait_reference->is_equal (*resolved))
 	return true;
 
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index 3d99794f3d6c..6f2589a0d2ba 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -216,8 +216,7 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference)
 	    // The one exception is the implicit Self type of a trait
 	    bool apply_sized = !is_self;
 	    auto param_type
-	      = TypeResolveGenericParam::Resolve (generic_param.get (),
-						  apply_sized);
+	      = TypeResolveGenericParam::Resolve (*generic_param, apply_sized);
 	    context->insert_type (generic_param->get_mappings (), param_type);
 	    substitutions.push_back (
 	      TyTy::SubstitutionParamMapping (typaram, param_type));
@@ -268,7 +267,7 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference)
 
 	      auto predicate = get_predicate_from_bound (
 		b->get_path (),
-		nullptr /*this will setup a PLACEHOLDER for self*/);
+		tl::nullopt /*this will setup a PLACEHOLDER for self*/);
 	      if (predicate.is_error ())
 		return &TraitReference::error_node ();
 
@@ -384,11 +383,11 @@ TraitItemReference::resolve_item (HIR::TraitItemFunc &func)
   auto expected_ret_tyty = resolved_fn_type->get_return_type ();
   context->push_return_type (TypeCheckContextItem (&func), expected_ret_tyty);
 
-  auto block_expr_ty = TypeCheckExpr::Resolve (func.get_block_expr ().get ());
+  auto block_expr_ty = TypeCheckExpr::Resolve (func.get_block_expr ());
 
   location_t fn_return_locus
     = func.get_decl ().has_return_type ()
-	? func.get_decl ().get_return_type ()->get_locus ()
+	? func.get_decl ().get_return_type ().get_locus ()
 	: func.get_locus ();
 
   coercion_site (func.get_mappings ().get_hirid (),
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.cc b/gcc/rust/typecheck/rust-hir-type-check-base.cc
index 7e34cef26c5e..d8b4b23f71da 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.cc
@@ -374,22 +374,21 @@ TypeCheckBase::resolve_generic_params (
 	  break;
 
 	  case HIR::GenericParam::GenericKind::CONST: {
-	    auto param
-	      = static_cast<HIR::ConstGenericParam *> (generic_param.get ());
-	    auto specified_type
-	      = TypeCheckType::Resolve (param->get_type ().get ());
+	    auto &param
+	      = static_cast<HIR::ConstGenericParam &> (*generic_param);
+	    auto specified_type = TypeCheckType::Resolve (param.get_type ());
 
-	    if (param->has_default_expression ())
+	    if (param.has_default_expression ())
 	      {
-		auto expr_type = TypeCheckExpr::Resolve (
-		  param->get_default_expression ().get ());
-
-		coercion_site (
-		  param->get_mappings ().get_hirid (),
-		  TyTy::TyWithLocation (specified_type),
-		  TyTy::TyWithLocation (
-		    expr_type, param->get_default_expression ()->get_locus ()),
-		  param->get_locus ());
+		auto expr_type
+		  = TypeCheckExpr::Resolve (param.get_default_expression ());
+
+		coercion_site (param.get_mappings ().get_hirid (),
+			       TyTy::TyWithLocation (specified_type),
+			       TyTy::TyWithLocation (
+				 expr_type,
+				 param.get_default_expression ().get_locus ()),
+			       param.get_locus ());
 	      }
 
 	    context->insert_type (generic_param->get_mappings (),
@@ -398,8 +397,7 @@ TypeCheckBase::resolve_generic_params (
 	  break;
 
 	  case HIR::GenericParam::GenericKind::TYPE: {
-	    auto param_type
-	      = TypeResolveGenericParam::Resolve (generic_param.get ());
+	    auto param_type = TypeResolveGenericParam::Resolve (*generic_param);
 	    context->insert_type (generic_param->get_mappings (), param_type);
 
 	    substitutions.push_back (TyTy::SubstitutionParamMapping (
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.h b/gcc/rust/typecheck/rust-hir-type-check-base.h
index 0bc29053a867..e720b9479161 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.h
@@ -37,10 +37,10 @@ protected:
 
   TraitReference *resolve_trait_path (HIR::TypePath &);
 
-  TyTy::TypeBoundPredicate
-  get_predicate_from_bound (HIR::TypePath &path, HIR::Type *associated_self,
-			    BoundPolarity polarity
-			    = BoundPolarity::RegularBound);
+  TyTy::TypeBoundPredicate get_predicate_from_bound (
+    HIR::TypePath &path,
+    tl::optional<std::reference_wrapper<HIR::Type>> associated_self,
+    BoundPolarity polarity = BoundPolarity::RegularBound);
 
   bool check_for_unconstrained (
     const std::vector<TyTy::SubstitutionParamMapping> &params_to_constrain,
@@ -55,7 +55,7 @@ protected:
 						 location_t locus);
 
   void resolve_generic_params (
-    const std::vector<std::unique_ptr<HIR::GenericParam> > &generic_params,
+    const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params,
     std::vector<TyTy::SubstitutionParamMapping> &substitutions);
 
   TyTy::TypeBoundPredicate get_marker_predicate (LangItem::Kind item_type,
diff --git a/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc b/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc
index a9154c647867..22025cef68aa 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc
@@ -16,6 +16,7 @@
 // along with GCC; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
+#include "rust-hir-expr.h"
 #include "rust-hir-type-check-type.h"
 #include "rust-hir-type-check-expr.h"
 #include "rust-hir-type-check-enumitem.h"
@@ -29,25 +30,25 @@ namespace Rust {
 namespace Resolver {
 
 TyTy::VariantDef *
-TypeCheckEnumItem::Resolve (HIR::EnumItem *item, int64_t last_discriminant)
+TypeCheckEnumItem::Resolve (HIR::EnumItem &item, int64_t last_discriminant)
 {
   TypeCheckEnumItem resolver (last_discriminant);
-  switch (item->get_enum_item_kind ())
+  switch (item.get_enum_item_kind ())
     {
     case HIR::EnumItem::EnumItemKind::Named:
-      resolver.visit (static_cast<HIR::EnumItem &> (*item));
+      resolver.visit (static_cast<HIR::EnumItem &> (item));
       break;
 
     case HIR::EnumItem::EnumItemKind::Tuple:
-      resolver.visit (static_cast<HIR::EnumItemTuple &> (*item));
+      resolver.visit (static_cast<HIR::EnumItemTuple &> (item));
       break;
 
     case HIR::EnumItem::EnumItemKind::Struct:
-      resolver.visit (static_cast<HIR::EnumItemStruct &> (*item));
+      resolver.visit (static_cast<HIR::EnumItemStruct &> (item));
       break;
 
     case HIR::EnumItem::EnumItemKind::Discriminant:
-      resolver.visit (static_cast<HIR::EnumItemDiscriminant &> (*item));
+      resolver.visit (static_cast<HIR::EnumItemDiscriminant &> (item));
       break;
     }
   return resolver.variant;
@@ -68,11 +69,10 @@ TypeCheckEnumItem::visit (HIR::EnumItem &item)
 				 mappings.get_next_hir_id (
 				   item.get_mappings ().get_crate_num ()),
 				 item.get_mappings ().get_local_defid ());
-  HIR::LiteralExpr *discim_expr
-    = new HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
-			    HIR::Literal::LitType::INT,
-			    PrimitiveCoreType::CORETYPE_I64, item.get_locus (),
-			    {});
+  auto discim_expr = Rust::make_unique<HIR::LiteralExpr> (
+    HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
+		      HIR::Literal::LitType::INT,
+		      PrimitiveCoreType::CORETYPE_I64, item.get_locus (), {}));
 
   TyTy::BaseType *isize = nullptr;
   bool ok = context->lookup_builtin ("isize", &isize);
@@ -101,7 +101,7 @@ TypeCheckEnumItem::visit (HIR::EnumItem &item)
   variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
 				  item.get_mappings ().get_defid (),
 				  item.get_identifier ().as_string (), ident,
-				  discim_expr);
+				  std::move (discim_expr));
 }
 
 void
@@ -111,13 +111,13 @@ TypeCheckEnumItem::visit (HIR::EnumItemDiscriminant &item)
     rust_error_at (item.get_locus (), "discriminant too big");
 
   auto &discriminant = item.get_discriminant_expression ();
-  auto capacity_type = TypeCheckExpr::Resolve (discriminant.get ());
+  auto capacity_type = TypeCheckExpr::Resolve (discriminant);
   if (capacity_type->get_kind () == TyTy::TypeKind::ERROR)
     return;
 
   TyTy::ISizeType *expected_ty
-    = new TyTy::ISizeType (discriminant->get_mappings ().get_hirid ());
-  context->insert_type (discriminant->get_mappings (), expected_ty);
+    = new TyTy::ISizeType (discriminant.get_mappings ().get_hirid ());
+  context->insert_type (discriminant.get_mappings (), expected_ty);
 
   unify_site (item.get_mappings ().get_hirid (),
 	      TyTy::TyWithLocation (expected_ty),
@@ -145,7 +145,7 @@ TypeCheckEnumItem::visit (HIR::EnumItemDiscriminant &item)
   variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
 				  item.get_mappings ().get_defid (),
 				  item.get_identifier ().as_string (), ident,
-				  item.get_discriminant_expression ().get ());
+				  item.take_discriminant_expression ());
 }
 
 void
@@ -159,7 +159,7 @@ TypeCheckEnumItem::visit (HIR::EnumItemTuple &item)
   for (auto &field : item.get_tuple_fields ())
     {
       TyTy::BaseType *field_type
-	= TypeCheckType::Resolve (field.get_field_type ().get ());
+	= TypeCheckType::Resolve (field.get_field_type ());
       TyTy::StructFieldType *ty_field
 	= new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
 				     std::to_string (idx), field_type,
@@ -174,11 +174,10 @@ TypeCheckEnumItem::visit (HIR::EnumItemTuple &item)
 				 mappings.get_next_hir_id (
 				   item.get_mappings ().get_crate_num ()),
 				 item.get_mappings ().get_local_defid ());
-  HIR::LiteralExpr *discim_expr
-    = new HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
-			    HIR::Literal::LitType::INT,
-			    PrimitiveCoreType::CORETYPE_I64, item.get_locus (),
-			    {});
+  auto discim_expr = Rust::make_unique<HIR::LiteralExpr> (
+    HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
+		      HIR::Literal::LitType::INT,
+		      PrimitiveCoreType::CORETYPE_I64, item.get_locus (), {}));
 
   TyTy::BaseType *isize = nullptr;
   bool ok = context->lookup_builtin ("isize", &isize);
@@ -208,7 +207,7 @@ TypeCheckEnumItem::visit (HIR::EnumItemTuple &item)
 				  item.get_mappings ().get_defid (),
 				  item.get_identifier ().as_string (), ident,
 				  TyTy::VariantDef::VariantType::TUPLE,
-				  discim_expr, fields);
+				  std::move (discim_expr), fields);
 }
 
 void
@@ -221,7 +220,7 @@ TypeCheckEnumItem::visit (HIR::EnumItemStruct &item)
   for (auto &field : item.get_struct_fields ())
     {
       TyTy::BaseType *field_type
-	= TypeCheckType::Resolve (field.get_field_type ().get ());
+	= TypeCheckType::Resolve (field.get_field_type ());
       TyTy::StructFieldType *ty_field
 	= new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
 				     field.get_field_name ().as_string (),
@@ -235,11 +234,10 @@ TypeCheckEnumItem::visit (HIR::EnumItemStruct &item)
 				 mappings.get_next_hir_id (
 				   item.get_mappings ().get_crate_num ()),
 				 item.get_mappings ().get_local_defid ());
-  HIR::LiteralExpr *discrim_expr
-    = new HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
-			    HIR::Literal::LitType::INT,
-			    PrimitiveCoreType::CORETYPE_I64, item.get_locus (),
-			    {});
+  auto discrim_expr = Rust::make_unique<HIR::LiteralExpr> (
+    HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
+		      HIR::Literal::LitType::INT,
+		      PrimitiveCoreType::CORETYPE_I64, item.get_locus (), {}));
 
   TyTy::BaseType *isize = nullptr;
   bool ok = context->lookup_builtin ("isize", &isize);
@@ -269,7 +267,7 @@ TypeCheckEnumItem::visit (HIR::EnumItemStruct &item)
 				  item.get_mappings ().get_defid (),
 				  item.get_identifier ().as_string (), ident,
 				  TyTy::VariantDef::VariantType::STRUCT,
-				  discrim_expr, fields);
+				  std::move (discrim_expr), fields);
 }
 
 } // namespace Resolver
diff --git a/gcc/rust/typecheck/rust-hir-type-check-enumitem.h b/gcc/rust/typecheck/rust-hir-type-check-enumitem.h
index bccffe7e8d34..6b01a49b0f31 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-enumitem.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-enumitem.h
@@ -28,7 +28,7 @@ namespace Resolver {
 class TypeCheckEnumItem : public TypeCheckBase
 {
 public:
-  static TyTy::VariantDef *Resolve (HIR::EnumItem *item,
+  static TyTy::VariantDef *Resolve (HIR::EnumItem &item,
 				    int64_t last_discriminant);
 
 protected:
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 225d83624e00..32e3839930cf 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -36,17 +36,17 @@ TypeCheckExpr::TypeCheckExpr () : TypeCheckBase (), infered (nullptr) {}
 // Perform type checking on expr. Also runs type unification algorithm.
 // Returns the unified type of expr
 TyTy::BaseType *
-TypeCheckExpr::Resolve (HIR::Expr *expr)
+TypeCheckExpr::Resolve (HIR::Expr &expr)
 {
   TypeCheckExpr resolver;
-  expr->accept_vis (resolver);
+  expr.accept_vis (resolver);
 
   if (resolver.infered == nullptr)
-    return new TyTy::ErrorType (expr->get_mappings ().get_hirid ());
+    return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
 
-  auto ref = expr->get_mappings ().get_hirid ();
+  auto ref = expr.get_mappings ().get_hirid ();
   resolver.infered->set_ref (ref);
-  resolver.context->insert_type (expr->get_mappings (), resolver.infered);
+  resolver.context->insert_type (expr.get_mappings (), resolver.infered);
 
   return resolver.infered;
 }
@@ -54,10 +54,10 @@ TypeCheckExpr::Resolve (HIR::Expr *expr)
 void
 TypeCheckExpr::visit (HIR::TupleIndexExpr &expr)
 {
-  auto resolved = TypeCheckExpr::Resolve (expr.get_tuple_expr ().get ());
+  auto resolved = TypeCheckExpr::Resolve (expr.get_tuple_expr ());
   if (resolved->get_kind () == TyTy::TypeKind::ERROR)
     {
-      rust_error_at (expr.get_tuple_expr ()->get_locus (),
+      rust_error_at (expr.get_tuple_expr ().get_locus (),
 		     "failed to resolve TupleIndexExpr receiver");
       return;
     }
@@ -73,7 +73,7 @@ TypeCheckExpr::visit (HIR::TupleIndexExpr &expr)
 		       || resolved->get_kind () == TyTy::TypeKind::TUPLE;
   if (!is_valid_type)
     {
-      rust_error_at (expr.get_tuple_expr ()->get_locus (),
+      rust_error_at (expr.get_tuple_expr ().get_locus (),
 		     "Expected Tuple or ADT got: %s",
 		     resolved->as_string ().c_str ());
       return;
@@ -138,7 +138,7 @@ TypeCheckExpr::visit (HIR::TupleExpr &expr)
   std::vector<TyTy::TyVar> fields;
   for (auto &elem : expr.get_tuple_elems ())
     {
-      auto field_ty = TypeCheckExpr::Resolve (elem.get ());
+      auto field_ty = TypeCheckExpr::Resolve (*elem);
       fields.push_back (TyTy::TyVar (field_ty->get_ref ()));
     }
   infered = new TyTy::TupleType (expr.get_mappings ().get_hirid (),
@@ -158,10 +158,11 @@ TypeCheckExpr::visit (HIR::ReturnExpr &expr)
 
   auto fn_return_tyty = context->peek_return_type ();
   location_t expr_locus = expr.has_return_expr ()
-			    ? expr.get_expr ()->get_locus ()
+			    ? expr.get_expr ().get_locus ()
 			    : expr.get_locus ();
+
   TyTy::BaseType *expr_ty = expr.has_return_expr ()
-			      ? TypeCheckExpr::Resolve (expr.get_expr ().get ())
+			      ? TypeCheckExpr::Resolve (expr.get_expr ())
 			      : TyTy::TupleType::get_unit_type ();
 
   coercion_site (expr.get_mappings ().get_hirid (),
@@ -174,8 +175,7 @@ TypeCheckExpr::visit (HIR::ReturnExpr &expr)
 void
 TypeCheckExpr::visit (HIR::CallExpr &expr)
 {
-  TyTy::BaseType *function_tyty
-    = TypeCheckExpr::Resolve (expr.get_fnexpr ().get ());
+  TyTy::BaseType *function_tyty = TypeCheckExpr::Resolve (expr.get_fnexpr ());
 
   rust_debug_loc (expr.get_locus (), "resolved_call_expr to: {%s}",
 		  function_tyty->get_name ().c_str ());
@@ -189,7 +189,7 @@ TypeCheckExpr::visit (HIR::CallExpr &expr)
 	  // lookup variant id
 	  HirId variant_id;
 	  bool ok = context->lookup_variant_definition (
-	    expr.get_fnexpr ()->get_mappings ().get_hirid (), &variant_id);
+	    expr.get_fnexpr ().get_mappings ().get_hirid (), &variant_id);
 
 	  if (!ok)
 	    {
@@ -203,12 +203,12 @@ TypeCheckExpr::visit (HIR::CallExpr &expr)
 	  ok = adt->lookup_variant_by_id (variant_id, &lookup_variant);
 	  rust_assert (ok);
 
-	  variant = *lookup_variant;
+	  variant = std::move (*lookup_variant);
 	}
       else
 	{
 	  rust_assert (adt->number_of_variants () == 1);
-	  variant = *adt->get_variants ().at (0);
+	  variant = std::move (*adt->get_variants ().at (0));
 	}
 
       infered
@@ -238,12 +238,12 @@ TypeCheckExpr::visit (HIR::AssignmentExpr &expr)
 {
   infered = TyTy::TupleType::get_unit_type ();
 
-  auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ().get ());
-  auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ().get ());
+  auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ());
+  auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ());
 
   coercion_site (expr.get_mappings ().get_hirid (),
-		 TyTy::TyWithLocation (lhs, expr.get_lhs ()->get_locus ()),
-		 TyTy::TyWithLocation (rhs, expr.get_rhs ()->get_locus ()),
+		 TyTy::TyWithLocation (lhs, expr.get_lhs ().get_locus ()),
+		 TyTy::TyWithLocation (rhs, expr.get_rhs ().get_locus ()),
 		 expr.get_locus ());
 }
 
@@ -252,14 +252,14 @@ TypeCheckExpr::visit (HIR::CompoundAssignmentExpr &expr)
 {
   infered = TyTy::TupleType::get_unit_type ();
 
-  auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ().get ());
-  auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ().get ());
+  auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ());
+  auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ());
 
   // we dont care about the result of the unify from a compound assignment
   // since this is a unit-type expr
   coercion_site (expr.get_mappings ().get_hirid (),
-		 TyTy::TyWithLocation (lhs, expr.get_lhs ()->get_locus ()),
-		 TyTy::TyWithLocation (rhs, expr.get_rhs ()->get_locus ()),
+		 TyTy::TyWithLocation (lhs, expr.get_lhs ().get_locus ()),
+		 TyTy::TyWithLocation (rhs, expr.get_rhs ().get_locus ()),
 		 expr.get_locus ());
 
   auto lang_item_type
@@ -292,8 +292,8 @@ TypeCheckExpr::visit (HIR::LiteralExpr &expr)
 void
 TypeCheckExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
 {
-  auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ().get ());
-  auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ().get ());
+  auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ());
+  auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ());
 
   auto lang_item_type = LangItem::OperatorToLangItem (expr.get_expr_type ());
   bool operator_overloaded
@@ -317,8 +317,8 @@ TypeCheckExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
     {
     case ArithmeticOrLogicalOperator::LEFT_SHIFT:
       case ArithmeticOrLogicalOperator::RIGHT_SHIFT: {
-	TyTy::TyWithLocation from (rhs, expr.get_rhs ()->get_locus ());
-	TyTy::TyWithLocation to (lhs, expr.get_lhs ()->get_locus ());
+	TyTy::TyWithLocation from (rhs, expr.get_rhs ().get_locus ());
+	TyTy::TyWithLocation to (lhs, expr.get_lhs ().get_locus ());
 	infered = cast_site (expr.get_mappings ().get_hirid (), from, to,
 			     expr.get_locus ());
       }
@@ -327,8 +327,8 @@ TypeCheckExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
       default: {
 	infered = unify_site (
 	  expr.get_mappings ().get_hirid (),
-	  TyTy::TyWithLocation (lhs, expr.get_lhs ()->get_locus ()),
-	  TyTy::TyWithLocation (rhs, expr.get_rhs ()->get_locus ()),
+	  TyTy::TyWithLocation (lhs, expr.get_lhs ().get_locus ()),
+	  TyTy::TyWithLocation (rhs, expr.get_rhs ().get_locus ()),
 	  expr.get_locus ());
       }
       break;
@@ -338,12 +338,12 @@ TypeCheckExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
 void
 TypeCheckExpr::visit (HIR::ComparisonExpr &expr)
 {
-  auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ().get ());
-  auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ().get ());
+  auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ());
+  auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ());
 
   unify_site (expr.get_mappings ().get_hirid (),
-	      TyTy::TyWithLocation (lhs, expr.get_lhs ()->get_locus ()),
-	      TyTy::TyWithLocation (rhs, expr.get_rhs ()->get_locus ()),
+	      TyTy::TyWithLocation (lhs, expr.get_lhs ().get_locus ()),
+	      TyTy::TyWithLocation (rhs, expr.get_rhs ().get_locus ()),
 	      expr.get_locus ());
 
   bool ok = context->lookup_builtin ("bool", &infered);
@@ -353,8 +353,8 @@ TypeCheckExpr::visit (HIR::ComparisonExpr &expr)
 void
 TypeCheckExpr::visit (HIR::LazyBooleanExpr &expr)
 {
-  auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ().get ());
-  auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ().get ());
+  auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ());
+  auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ());
 
   // we expect the lhs and rhs must be bools at this point
   TyTy::BaseType *boolean_node = nullptr;
@@ -364,27 +364,27 @@ TypeCheckExpr::visit (HIR::LazyBooleanExpr &expr)
   // verify the lhs and rhs before unifying together
   lhs = unify_site (expr.get_mappings ().get_hirid (),
 		    TyTy::TyWithLocation (boolean_node,
-					  expr.get_lhs ()->get_locus ()),
-		    TyTy::TyWithLocation (lhs, expr.get_lhs ()->get_locus ()),
+					  expr.get_lhs ().get_locus ()),
+		    TyTy::TyWithLocation (lhs, expr.get_lhs ().get_locus ()),
 		    expr.get_locus ());
 
   rhs = unify_site (expr.get_mappings ().get_hirid (),
 		    TyTy::TyWithLocation (boolean_node,
-					  expr.get_rhs ()->get_locus ()),
-		    TyTy::TyWithLocation (rhs, expr.get_rhs ()->get_locus ()),
+					  expr.get_rhs ().get_locus ()),
+		    TyTy::TyWithLocation (rhs, expr.get_rhs ().get_locus ()),
 		    expr.get_locus ());
 
   infered
     = unify_site (expr.get_mappings ().get_hirid (),
-		  TyTy::TyWithLocation (lhs, expr.get_lhs ()->get_locus ()),
-		  TyTy::TyWithLocation (rhs, expr.get_rhs ()->get_locus ()),
+		  TyTy::TyWithLocation (lhs, expr.get_lhs ().get_locus ()),
+		  TyTy::TyWithLocation (rhs, expr.get_rhs ().get_locus ()),
 		  expr.get_locus ());
 }
 
 void
 TypeCheckExpr::visit (HIR::NegationExpr &expr)
 {
-  auto negated_expr_ty = TypeCheckExpr::Resolve (expr.get_expr ().get ());
+  auto negated_expr_ty = TypeCheckExpr::Resolve (expr.get_expr ());
 
   // check for operator overload
   auto lang_item_type
@@ -449,15 +449,14 @@ TypeCheckExpr::visit (HIR::IfExpr &expr)
   bool ok = context->lookup_builtin ("bool", &bool_ty);
   rust_assert (ok);
 
-  TyTy::BaseType *cond_type
-    = TypeCheckExpr::Resolve (expr.get_if_condition ().get ());
+  TyTy::BaseType *cond_type = TypeCheckExpr::Resolve (expr.get_if_condition ());
 
   unify_site (expr.get_mappings ().get_hirid (), TyTy::TyWithLocation (bool_ty),
 	      TyTy::TyWithLocation (cond_type,
-				    expr.get_if_condition ()->get_locus ()),
+				    expr.get_if_condition ().get_locus ()),
 	      expr.get_locus ());
 
-  TypeCheckExpr::Resolve (expr.get_if_block ().get ());
+  TypeCheckExpr::Resolve (expr.get_if_block ());
 
   infered = TyTy::TupleType::get_unit_type ();
 }
@@ -469,17 +468,15 @@ TypeCheckExpr::visit (HIR::IfExprConseqElse &expr)
   bool ok = context->lookup_builtin ("bool", &bool_ty);
   rust_assert (ok);
 
-  TyTy::BaseType *cond_type
-    = TypeCheckExpr::Resolve (expr.get_if_condition ().get ());
+  TyTy::BaseType *cond_type = TypeCheckExpr::Resolve (expr.get_if_condition ());
 
   unify_site (expr.get_mappings ().get_hirid (), TyTy::TyWithLocation (bool_ty),
 	      TyTy::TyWithLocation (cond_type,
-				    expr.get_if_condition ()->get_locus ()),
+				    expr.get_if_condition ().get_locus ()),
 	      expr.get_locus ());
 
-  auto if_blk_resolved = TypeCheckExpr::Resolve (expr.get_if_block ().get ());
-  auto else_blk_resolved
-    = TypeCheckExpr::Resolve (expr.get_else_block ().get ());
+  auto if_blk_resolved = TypeCheckExpr::Resolve (expr.get_if_block ());
+  auto else_blk_resolved = TypeCheckExpr::Resolve (expr.get_else_block ());
 
   if (if_blk_resolved->get_kind () == TyTy::NEVER)
     infered = else_blk_resolved;
@@ -487,20 +484,20 @@ TypeCheckExpr::visit (HIR::IfExprConseqElse &expr)
     infered = if_blk_resolved;
   else
     {
-      infered = unify_site (
-	expr.get_mappings ().get_hirid (),
-	TyTy::TyWithLocation (if_blk_resolved,
-			      expr.get_if_block ()->get_locus ()),
-	TyTy::TyWithLocation (else_blk_resolved,
-			      expr.get_else_block ()->get_locus ()),
-	expr.get_locus ());
+      infered
+	= unify_site (expr.get_mappings ().get_hirid (),
+		      TyTy::TyWithLocation (if_blk_resolved,
+					    expr.get_if_block ().get_locus ()),
+		      TyTy::TyWithLocation (
+			else_blk_resolved, expr.get_else_block ().get_locus ()),
+		      expr.get_locus ());
     }
 }
 
 void
 TypeCheckExpr::visit (HIR::UnsafeBlockExpr &expr)
 {
-  infered = TypeCheckExpr::Resolve (expr.get_block_expr ().get ());
+  infered = TypeCheckExpr::Resolve (expr.get_block_expr ());
 }
 
 void
@@ -515,7 +512,7 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr)
       if (!s->is_item ())
 	continue;
 
-      TypeCheckStmt::Resolve (s.get ());
+      TypeCheckStmt::Resolve (*s);
     }
 
   for (auto &s : expr.get_statements ())
@@ -523,7 +520,7 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr)
       if (s->is_item ())
 	continue;
 
-      auto resolved = TypeCheckStmt::Resolve (s.get ());
+      auto resolved = TypeCheckStmt::Resolve (*s);
       if (resolved == nullptr)
 	{
 	  rust_error_at (s->get_locus (), "failure to resolve type");
@@ -541,7 +538,7 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr)
     }
 
   if (expr.has_expr ())
-    infered = TypeCheckExpr::Resolve (expr.get_final_expr ().get ())->clone ();
+    infered = TypeCheckExpr::Resolve (expr.get_final_expr ())->clone ();
   else if (expr.is_tail_reachable ())
     infered = TyTy::TupleType::get_unit_type ();
   else if (expr.has_label ())
@@ -595,14 +592,13 @@ TypeCheckExpr::visit (HIR::RangeFromToExpr &expr)
 
   // resolve the range expressions and these types must unify then we use that
   // type to substitute into the ADT
-  TyTy::BaseType *from_ty
-    = TypeCheckExpr::Resolve (expr.get_from_expr ().get ());
-  TyTy::BaseType *to_ty = TypeCheckExpr::Resolve (expr.get_to_expr ().get ());
+  TyTy::BaseType *from_ty = TypeCheckExpr::Resolve (expr.get_from_expr ());
+  TyTy::BaseType *to_ty = TypeCheckExpr::Resolve (expr.get_to_expr ());
 
   TyTy::BaseType *unified = unify_site (
     expr.get_mappings ().get_hirid (),
-    TyTy::TyWithLocation (from_ty, expr.get_from_expr ()->get_locus ()),
-    TyTy::TyWithLocation (to_ty, expr.get_to_expr ()->get_locus ()),
+    TyTy::TyWithLocation (from_ty, expr.get_from_expr ().get_locus ()),
+    TyTy::TyWithLocation (to_ty, expr.get_to_expr ().get_locus ()),
     expr.get_locus ());
 
   // substitute it in
@@ -647,8 +643,7 @@ TypeCheckExpr::visit (HIR::RangeFromExpr &expr)
 
   // resolve the range expressions and these types must unify then we use that
   // type to substitute into the ADT
-  TyTy::BaseType *from_ty
-    = TypeCheckExpr::Resolve (expr.get_from_expr ().get ());
+  TyTy::BaseType *from_ty = TypeCheckExpr::Resolve (expr.get_from_expr ());
 
   // substitute it in
   std::vector<TyTy::SubstitutionArg> subst_mappings;
@@ -692,7 +687,7 @@ TypeCheckExpr::visit (HIR::RangeToExpr &expr)
 
   // resolve the range expressions and these types must unify then we use that
   // type to substitute into the ADT
-  TyTy::BaseType *from_ty = TypeCheckExpr::Resolve (expr.get_to_expr ().get ());
+  TyTy::BaseType *from_ty = TypeCheckExpr::Resolve (expr.get_to_expr ());
 
   // substitute it in
   std::vector<TyTy::SubstitutionArg> subst_mappings;
@@ -716,38 +711,38 @@ typecheck_inline_asm_operand (HIR::InlineAsm &expr)
 	{
 	  case RegisterType::In: {
 	    auto in = operand.get_in ();
-	    TypeCheckExpr::Resolve (in.expr.get ());
+	    TypeCheckExpr::Resolve (*in.expr);
 	    break;
 	  }
 	  case RegisterType::Out: {
 	    auto out = operand.get_out ();
-	    TypeCheckExpr::Resolve (out.expr.get ());
+	    TypeCheckExpr::Resolve (*out.expr);
 	    break;
 	  }
 	  case RegisterType::InOut: {
 	    auto in_out = operand.get_in_out ();
-	    TypeCheckExpr::Resolve (in_out.expr.get ());
+	    TypeCheckExpr::Resolve (*in_out.expr);
 	    break;
 	  }
 	  case RegisterType::SplitInOut: {
 	    auto split_in_out = operand.get_split_in_out ();
-	    TypeCheckExpr::Resolve (split_in_out.in_expr.get ());
-	    TypeCheckExpr::Resolve (split_in_out.out_expr.get ());
+	    TypeCheckExpr::Resolve (*split_in_out.in_expr);
+	    TypeCheckExpr::Resolve (*split_in_out.out_expr);
 	    break;
 	  }
 	  case RegisterType::Const: {
 	    auto anon_const = operand.get_const ().anon_const;
-	    TypeCheckExpr::Resolve (anon_const.expr.get ());
+	    TypeCheckExpr::Resolve (*anon_const.expr);
 	    break;
 	  }
 	  case RegisterType::Sym: {
 	    auto sym = operand.get_sym ();
-	    TypeCheckExpr::Resolve (sym.expr.get ());
+	    TypeCheckExpr::Resolve (*sym.expr);
 	    break;
 	  }
 	  case RegisterType::Label: {
 	    auto label = operand.get_label ();
-	    TypeCheckExpr::Resolve (label.expr.get ());
+	    TypeCheckExpr::Resolve (*label.expr);
 	    break;
 	  }
 	}
@@ -826,13 +821,12 @@ TypeCheckExpr::visit (HIR::RangeFromToInclExpr &expr)
 
   // resolve the range expressions and these types must unify then we use that
   // type to substitute into the ADT
-  TyTy::BaseType *from_ty
-    = TypeCheckExpr::Resolve (expr.get_from_expr ().get ());
-  TyTy::BaseType *to_ty = TypeCheckExpr::Resolve (expr.get_to_expr ().get ());
+  TyTy::BaseType *from_ty = TypeCheckExpr::Resolve (expr.get_from_expr ());
+  TyTy::BaseType *to_ty = TypeCheckExpr::Resolve (expr.get_to_expr ());
   TyTy::BaseType *unified = unify_site (
     expr.get_mappings ().get_hirid (),
-    TyTy::TyWithLocation (from_ty, expr.get_from_expr ()->get_locus ()),
-    TyTy::TyWithLocation (to_ty, expr.get_to_expr ()->get_locus ()),
+    TyTy::TyWithLocation (from_ty, expr.get_from_expr ().get_locus ()),
+    TyTy::TyWithLocation (to_ty, expr.get_to_expr ().get_locus ()),
     expr.get_locus ());
 
   // substitute it in
@@ -849,11 +843,11 @@ TypeCheckExpr::visit (HIR::RangeFromToInclExpr &expr)
 void
 TypeCheckExpr::visit (HIR::ArrayIndexExpr &expr)
 {
-  auto array_expr_ty = TypeCheckExpr::Resolve (expr.get_array_expr ().get ());
+  auto array_expr_ty = TypeCheckExpr::Resolve (expr.get_array_expr ());
   if (array_expr_ty->get_kind () == TyTy::TypeKind::ERROR)
     return;
 
-  auto index_expr_ty = TypeCheckExpr::Resolve (expr.get_index_expr ().get ());
+  auto index_expr_ty = TypeCheckExpr::Resolve (expr.get_index_expr ());
   if (index_expr_ty->get_kind () == TyTy::TypeKind::ERROR)
     return;
 
@@ -876,10 +870,10 @@ TypeCheckExpr::visit (HIR::ArrayIndexExpr &expr)
   if (maybe_simple_array_access
       && direct_array_expr_ty->get_kind () == TyTy::TypeKind::ARRAY)
     {
-      unify_site (expr.get_index_expr ()->get_mappings ().get_hirid (),
+      unify_site (expr.get_index_expr ().get_mappings ().get_hirid (),
 		  TyTy::TyWithLocation (size_ty),
 		  TyTy::TyWithLocation (index_expr_ty,
-					expr.get_index_expr ()->get_locus ()),
+					expr.get_index_expr ().get_locus ()),
 		  expr.get_locus ());
 
       TyTy::ArrayType *array_type
@@ -906,8 +900,8 @@ TypeCheckExpr::visit (HIR::ArrayIndexExpr &expr)
 
   // error[E0277]: the type `[{integer}]` cannot be indexed by `u32`
   rich_location r (line_table, expr.get_locus ());
-  r.add_range (expr.get_array_expr ()->get_locus ());
-  r.add_range (expr.get_index_expr ()->get_locus ());
+  r.add_range (expr.get_array_expr ().get_locus ());
+  r.add_range (expr.get_index_expr ().get_locus ());
   rust_error_at (r, ErrorCode::E0277,
 		 "the type %qs cannot be indexed by %qs",
 		 array_expr_ty->get_name ().c_str (),
@@ -917,7 +911,7 @@ TypeCheckExpr::visit (HIR::ArrayIndexExpr &expr)
 void
 TypeCheckExpr::visit (HIR::ArrayExpr &expr)
 {
-  HIR::ArrayElems &elements = *expr.get_internal_elements ();
+  auto &elements = expr.get_internal_elements ();
 
   HIR::Expr *capacity_expr = nullptr;
   TyTy::BaseType *element_type = nullptr;
@@ -926,25 +920,24 @@ TypeCheckExpr::visit (HIR::ArrayExpr &expr)
       case HIR::ArrayElems::ArrayExprType::COPIED: {
 	HIR::ArrayElemsCopied &elems
 	  = static_cast<HIR::ArrayElemsCopied &> (elements);
-	element_type
-	  = TypeCheckExpr::Resolve (elems.get_elem_to_copy ().get ());
+	element_type = TypeCheckExpr::Resolve (elems.get_elem_to_copy ());
 
 	auto capacity_type
-	  = TypeCheckExpr::Resolve (elems.get_num_copies_expr ().get ());
+	  = TypeCheckExpr::Resolve (elems.get_num_copies_expr ());
 
 	TyTy::BaseType *expected_ty = nullptr;
 	bool ok = context->lookup_builtin ("usize", &expected_ty);
 	rust_assert (ok);
-	context->insert_type (elems.get_num_copies_expr ()->get_mappings (),
+	context->insert_type (elems.get_num_copies_expr ().get_mappings (),
 			      expected_ty);
 
-	unify_site (
-	  expr.get_mappings ().get_hirid (), TyTy::TyWithLocation (expected_ty),
-	  TyTy::TyWithLocation (capacity_type,
-				elems.get_num_copies_expr ()->get_locus ()),
-	  expr.get_locus ());
+	unify_site (expr.get_mappings ().get_hirid (),
+		    TyTy::TyWithLocation (expected_ty),
+		    TyTy::TyWithLocation (
+		      capacity_type, elems.get_num_copies_expr ().get_locus ()),
+		    expr.get_locus ());
 
-	capacity_expr = elems.get_num_copies_expr ().get ();
+	capacity_expr = &elems.get_num_copies_expr ();
       }
       break;
 
@@ -955,7 +948,7 @@ TypeCheckExpr::visit (HIR::ArrayExpr &expr)
 	std::vector<TyTy::BaseType *> types;
 	for (auto &elem : elems.get_values ())
 	  {
-	    types.push_back (TypeCheckExpr::Resolve (elem.get ()));
+	    types.push_back (TypeCheckExpr::Resolve (*elem));
 	  }
 
 	// this is a LUB
@@ -999,7 +992,7 @@ void
 TypeCheckExpr::visit (HIR::StructExprStruct &struct_expr)
 {
   TyTy::BaseType *struct_path_ty
-    = TypeCheckExpr::Resolve (&struct_expr.get_struct_name ());
+    = TypeCheckExpr::Resolve (struct_expr.get_struct_name ());
   if (struct_path_ty->get_kind () != TyTy::TypeKind::ADT)
     {
       rust_error_at (struct_expr.get_struct_name ().get_locus (),
@@ -1031,19 +1024,19 @@ TypeCheckExpr::visit (HIR::StructExprStruct &struct_expr)
 void
 TypeCheckExpr::visit (HIR::StructExprStructFields &struct_expr)
 {
-  infered = TypeCheckStructExpr::Resolve (&struct_expr);
+  infered = TypeCheckStructExpr::Resolve (struct_expr);
 }
 
 void
 TypeCheckExpr::visit (HIR::GroupedExpr &expr)
 {
-  infered = TypeCheckExpr::Resolve (expr.get_expr_in_parens ().get ());
+  infered = TypeCheckExpr::Resolve (expr.get_expr_in_parens ());
 }
 
 void
 TypeCheckExpr::visit (HIR::FieldAccessExpr &expr)
 {
-  auto struct_base = TypeCheckExpr::Resolve (expr.get_receiver_expr ().get ());
+  auto struct_base = TypeCheckExpr::Resolve (expr.get_receiver_expr ());
 
   // FIXME does this require autoderef here?
   if (struct_base->get_kind () == TyTy::TypeKind::REF)
@@ -1085,10 +1078,10 @@ TypeCheckExpr::visit (HIR::FieldAccessExpr &expr)
 void
 TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
 {
-  auto receiver_tyty = TypeCheckExpr::Resolve (expr.get_receiver ().get ());
+  auto receiver_tyty = TypeCheckExpr::Resolve (expr.get_receiver ());
   if (receiver_tyty->get_kind () == TyTy::TypeKind::ERROR)
     {
-      rust_error_at (expr.get_receiver ()->get_locus (),
+      rust_error_at (expr.get_receiver ().get_locus (),
 		     "failed to resolve receiver in MethodCallExpr");
       return;
     }
@@ -1147,7 +1140,7 @@ TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
   // 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_receiver ()->get_mappings ().get_hirid ();
+    = expr.get_receiver ().get_mappings ().get_hirid ();
   context->insert_autoderef_mappings (autoderef_mappings_id,
 				      std::move (candidate.adjustments));
 
@@ -1195,7 +1188,7 @@ TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
       if (impl_self_infer->get_kind () == TyTy::TypeKind::ERROR)
 	{
 	  rich_location r (line_table, expr.get_locus ());
-	  r.add_range (impl.get_type ()->get_locus ());
+	  r.add_range (impl.get_type ().get_locus ());
 	  rust_error_at (
 	    r, "failed to resolve impl type for method call resolution");
 	  return;
@@ -1267,11 +1260,10 @@ TypeCheckExpr::visit (HIR::LoopExpr &expr)
 {
   context->push_new_loop_context (expr.get_mappings ().get_hirid (),
 				  expr.get_locus ());
-  TyTy::BaseType *block_expr
-    = TypeCheckExpr::Resolve (expr.get_loop_block ().get ());
+  TyTy::BaseType *block_expr = TypeCheckExpr::Resolve (expr.get_loop_block ());
   if (!block_expr->is_unit ())
     {
-      rust_error_at (expr.get_loop_block ()->get_locus (),
+      rust_error_at (expr.get_loop_block ().get_locus (),
 		     "expected %<()%> got %s",
 		     block_expr->as_string ().c_str ());
       return;
@@ -1294,13 +1286,12 @@ TypeCheckExpr::visit (HIR::WhileLoopExpr &expr)
 {
   context->push_new_while_loop_context (expr.get_mappings ().get_hirid ());
 
-  TypeCheckExpr::Resolve (expr.get_predicate_expr ().get ());
-  TyTy::BaseType *block_expr
-    = TypeCheckExpr::Resolve (expr.get_loop_block ().get ());
+  TypeCheckExpr::Resolve (expr.get_predicate_expr ());
+  TyTy::BaseType *block_expr = TypeCheckExpr::Resolve (expr.get_loop_block ());
 
   if (!block_expr->is_unit ())
     {
-      rust_error_at (expr.get_loop_block ()->get_locus (),
+      rust_error_at (expr.get_loop_block ().get_locus (),
 		     "expected %<()%> got %s",
 		     block_expr->as_string ().c_str ());
       return;
@@ -1323,7 +1314,7 @@ TypeCheckExpr::visit (HIR::BreakExpr &expr)
   if (expr.has_break_expr ())
     {
       TyTy::BaseType *break_expr_tyty
-	= TypeCheckExpr::Resolve (expr.get_expr ().get ());
+	= TypeCheckExpr::Resolve (expr.get_expr ());
 
       TyTy::BaseType *loop_context = context->peek_loop_context ();
       if (loop_context->get_kind () == TyTy::TypeKind::ERROR)
@@ -1338,7 +1329,7 @@ TypeCheckExpr::visit (HIR::BreakExpr &expr)
 	= unify_site (expr.get_mappings ().get_hirid (),
 		      TyTy::TyWithLocation (loop_context),
 		      TyTy::TyWithLocation (break_expr_tyty,
-					    expr.get_expr ()->get_locus ()),
+					    expr.get_expr ().get_locus ()),
 		      expr.get_locus ());
       context->swap_head_loop_context (unified_ty);
     }
@@ -1362,8 +1353,7 @@ TypeCheckExpr::visit (HIR::ContinueExpr &expr)
 void
 TypeCheckExpr::visit (HIR::BorrowExpr &expr)
 {
-  TyTy::BaseType *resolved_base
-    = TypeCheckExpr::Resolve (expr.get_expr ().get ());
+  TyTy::BaseType *resolved_base = TypeCheckExpr::Resolve (expr.get_expr ());
 
   // In Rust this is valid because of DST's
   //
@@ -1393,8 +1383,7 @@ TypeCheckExpr::visit (HIR::BorrowExpr &expr)
 void
 TypeCheckExpr::visit (HIR::DereferenceExpr &expr)
 {
-  TyTy::BaseType *resolved_base
-    = TypeCheckExpr::Resolve (expr.get_expr ().get ());
+  TyTy::BaseType *resolved_base = TypeCheckExpr::Resolve (expr.get_expr ());
 
   rust_debug_loc (expr.get_locus (), "attempting deref operator overload");
   auto lang_item_type = LangItem::Kind::DEREF;
@@ -1435,14 +1424,14 @@ void
 TypeCheckExpr::visit (HIR::TypeCastExpr &expr)
 {
   TyTy::BaseType *expr_to_convert
-    = TypeCheckExpr::Resolve (expr.get_casted_expr ().get ());
+    = TypeCheckExpr::Resolve (expr.get_casted_expr ());
   TyTy::BaseType *tyty_to_convert_to
-    = TypeCheckType::Resolve (expr.get_type_to_convert_to ().get ());
+    = TypeCheckType::Resolve (expr.get_type_to_convert_to ());
 
   TyTy::TyWithLocation from (expr_to_convert,
-			     expr.get_casted_expr ()->get_locus ());
+			     expr.get_casted_expr ().get_locus ());
   TyTy::TyWithLocation to (tyty_to_convert_to,
-			   expr.get_type_to_convert_to ()->get_locus ());
+			   expr.get_type_to_convert_to ().get_locus ());
   infered = cast_site (expr.get_mappings ().get_hirid (), from, to,
 		       expr.get_locus ());
 }
@@ -1453,7 +1442,7 @@ TypeCheckExpr::visit (HIR::MatchExpr &expr)
   // this needs to perform a least upper bound coercion on the blocks and then
   // unify the scruintee and arms
   TyTy::BaseType *scrutinee_tyty
-    = TypeCheckExpr::Resolve (expr.get_scrutinee_expr ().get ());
+    = TypeCheckExpr::Resolve (expr.get_scrutinee_expr ());
 
   bool saw_error = false;
   std::vector<TyTy::BaseType *> kase_block_tys;
@@ -1464,7 +1453,7 @@ TypeCheckExpr::visit (HIR::MatchExpr &expr)
       for (auto &pattern : kase_arm.get_patterns ())
 	{
 	  TyTy::BaseType *kase_arm_ty
-	    = TypeCheckPattern::Resolve (pattern.get (), scrutinee_tyty);
+	    = TypeCheckPattern::Resolve (*pattern, scrutinee_tyty);
 	  if (kase_arm_ty->get_kind () == TyTy ::TypeKind::ERROR)
 	    {
 	      saw_error = true;
@@ -1474,7 +1463,7 @@ TypeCheckExpr::visit (HIR::MatchExpr &expr)
 	  TyTy::BaseType *checked_kase = unify_site (
 	    expr.get_mappings ().get_hirid (),
 	    TyTy::TyWithLocation (scrutinee_tyty,
-				  expr.get_scrutinee_expr ()->get_locus ()),
+				  expr.get_scrutinee_expr ().get_locus ()),
 	    TyTy::TyWithLocation (kase_arm_ty, pattern->get_locus ()),
 	    expr.get_locus ());
 	  if (checked_kase->get_kind () == TyTy::TypeKind::ERROR)
@@ -1485,8 +1474,7 @@ TypeCheckExpr::visit (HIR::MatchExpr &expr)
 	}
 
       // check the kase type
-      TyTy::BaseType *kase_block_ty
-	= TypeCheckExpr::Resolve (kase.get_expr ().get ());
+      TyTy::BaseType *kase_block_ty = TypeCheckExpr::Resolve (kase.get_expr ());
       kase_block_tys.push_back (kase_block_ty);
     }
   if (saw_error)
@@ -1529,17 +1517,17 @@ TypeCheckExpr::visit (HIR::ClosureExpr &expr)
       TyTy::BaseType *param_tyty = nullptr;
       if (p.has_type_given ())
 	{
-	  param_tyty = TypeCheckType::Resolve (p.get_type ().get ());
+	  param_tyty = TypeCheckType::Resolve (p.get_type ());
 	}
       else
 	{
-	  param_tyty = ClosureParamInfer::Resolve (p.get_pattern ().get ());
+	  param_tyty = ClosureParamInfer::Resolve (p.get_pattern ());
 	}
 
       TyTy::TyVar param_ty (param_tyty->get_ref ());
       parameter_types.push_back (param_ty);
 
-      TypeCheckPattern::Resolve (p.get_pattern ().get (), param_ty.get_tyty ());
+      TypeCheckPattern::Resolve (p.get_pattern (), param_ty.get_tyty ());
     }
 
   // we generate an implicit hirid for the closure args
@@ -1550,18 +1538,17 @@ TypeCheckExpr::visit (HIR::ClosureExpr &expr)
   context->insert_implicit_type (closure_args);
 
   location_t result_type_locus = expr.has_return_type ()
-				   ? expr.get_return_type ()->get_locus ()
+				   ? 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 ())
+	  TypeCheckType::Resolve (expr.get_return_type ())->get_ref ())
 	: TyTy::TyVar::get_implicit_infer_var (expr.get_locus ());
 
   // resolve the block
-  location_t closure_expr_locus = expr.get_expr ()->get_locus ();
-  TyTy::BaseType *closure_expr_ty
-    = TypeCheckExpr::Resolve (expr.get_expr ().get ());
+  location_t closure_expr_locus = expr.get_expr ().get_locus ();
+  TyTy::BaseType *closure_expr_ty = TypeCheckExpr::Resolve (expr.get_expr ());
   coercion_site (expr.get_mappings ().get_hirid (),
 		 TyTy::TyWithLocation (result_type.get_tyty (),
 				       result_type_locus),
@@ -1764,7 +1751,7 @@ TypeCheckExpr::resolve_operator_overload (LangItem::Kind lang_item_type,
       if (parent->has_trait_ref () && is_recursive_op)
 	{
 	  TraitReference *trait_reference
-	    = TraitResolver::Lookup (*parent->get_trait_ref ().get ());
+	    = TraitResolver::Lookup (parent->get_trait_ref ());
 	  if (!trait_reference->is_error ())
 	    {
 	      TyTy::BaseType *lookup = nullptr;
@@ -1804,7 +1791,7 @@ TypeCheckExpr::resolve_operator_overload (LangItem::Kind lang_item_type,
   // type check the arguments if required
   TyTy::FnType *type = static_cast<TyTy::FnType *> (lookup);
   rust_assert (type->num_params () > 0);
-  auto fnparam = type->param_at (0);
+  auto &fnparam = type->param_at (0);
 
   // typecheck the self
   unify_site (expr.get_mappings ().get_hirid (),
@@ -1817,7 +1804,7 @@ TypeCheckExpr::resolve_operator_overload (LangItem::Kind lang_item_type,
   else
     {
       rust_assert (type->num_params () == 2);
-      auto fnparam = type->param_at (1);
+      auto &fnparam = type->param_at (1);
       unify_site (expr.get_mappings ().get_hirid (),
 		  TyTy::TyWithLocation (fnparam.second),
 		  TyTy::TyWithLocation (rhs), expr.get_locus ());
@@ -1933,8 +1920,8 @@ TypeCheckExpr::resolve_fn_trait_call (HIR::CallExpr &expr,
   // 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
-  HIR::Expr *fnexpr = expr.get_fnexpr ().get ();
-  HirId autoderef_mappings_id = fnexpr->get_mappings ().get_hirid ();
+  HIR::Expr &fnexpr = expr.get_fnexpr ();
+  HirId autoderef_mappings_id = fnexpr.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);
@@ -1971,7 +1958,7 @@ TypeCheckExpr::resolve_fn_trait_call (HIR::CallExpr &expr,
   std::vector<TyTy::TyVar> call_args;
   for (auto &arg : expr.get_arguments ())
     {
-      TyTy::BaseType *a = TypeCheckExpr::Resolve (arg.get ());
+      TyTy::BaseType *a = TypeCheckExpr::Resolve (*arg);
       call_args.push_back (TyTy::TyVar (a->get_ref ()));
     }
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 997761144dba..82f421e326af 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -29,7 +29,7 @@ namespace Resolver {
 class TypeCheckExpr : private TypeCheckBase, private HIR::HIRExpressionVisitor
 {
 public:
-  static TyTy::BaseType *Resolve (HIR::Expr *expr);
+  static TyTy::BaseType *Resolve (HIR::Expr &expr);
 
   void visit (HIR::TupleIndexExpr &expr) override;
   void visit (HIR::TupleExpr &expr) override;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
index 19f25e4f8675..2173938fb15a 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
@@ -18,6 +18,8 @@
 
 #include "rust-hir-type-check-implitem.h"
 #include "rust-diagnostics.h"
+#include "rust-hir-full-decls.h"
+#include "rust-hir-pattern.h"
 #include "rust-hir-type-check-base.h"
 #include "rust-hir-type-check-type.h"
 #include "rust-hir-type-check-expr.h"
@@ -38,27 +40,26 @@ TypeCheckTopLevelExternItem::TypeCheckTopLevelExternItem (
 {}
 
 TyTy::BaseType *
-TypeCheckTopLevelExternItem::Resolve (HIR::ExternalItem *item,
+TypeCheckTopLevelExternItem::Resolve (HIR::ExternalItem &item,
 				      const HIR::ExternBlock &parent)
 {
   // is it already resolved?
   auto context = TypeCheckContext::get ();
   TyTy::BaseType *resolved = nullptr;
   bool already_resolved
-    = context->lookup_type (item->get_mappings ().get_hirid (), &resolved);
+    = context->lookup_type (item.get_mappings ().get_hirid (), &resolved);
   if (already_resolved)
     return resolved;
 
   TypeCheckTopLevelExternItem resolver (parent);
-  item->accept_vis (resolver);
+  item.accept_vis (resolver);
   return resolver.resolved;
 }
 
 void
 TypeCheckTopLevelExternItem::visit (HIR::ExternalStaticItem &item)
 {
-  TyTy::BaseType *actual_type
-    = TypeCheckType::Resolve (item.get_item_type ().get ());
+  TyTy::BaseType *actual_type = TypeCheckType::Resolve (item.get_item_type ());
 
   context->insert_type (item.get_mappings (), actual_type);
   resolved = actual_type;
@@ -89,7 +90,7 @@ TypeCheckTopLevelExternItem::visit (HIR::ExternalFunctionItem &function)
 
 	      case HIR::GenericParam::GenericKind::TYPE: {
 		auto param_type
-		  = TypeResolveGenericParam::Resolve (generic_param.get ());
+		  = TypeResolveGenericParam::Resolve (*generic_param);
 		context->insert_type (generic_param->get_mappings (),
 				      param_type);
 
@@ -106,7 +107,7 @@ TypeCheckTopLevelExternItem::visit (HIR::ExternalFunctionItem &function)
     {
       for (auto &where_clause_item : function.get_where_clause ().get_items ())
 	{
-	  ResolveWhereClauseItem::Resolve (*where_clause_item.get (),
+	  ResolveWhereClauseItem::Resolve (*where_clause_item,
 					   region_constraints);
 	}
     }
@@ -116,8 +117,7 @@ TypeCheckTopLevelExternItem::visit (HIR::ExternalFunctionItem &function)
     ret_type = TyTy::TupleType::get_unit_type ();
   else
     {
-      auto resolved
-	= TypeCheckType::Resolve (function.get_return_type ().get ());
+      auto resolved = TypeCheckType::Resolve (function.get_return_type ());
       if (resolved == nullptr)
 	{
 	  rust_error_at (function.get_locus (),
@@ -127,14 +127,15 @@ TypeCheckTopLevelExternItem::visit (HIR::ExternalFunctionItem &function)
 
       ret_type = resolved->clone ();
       ret_type->set_ref (
-	function.get_return_type ()->get_mappings ().get_hirid ());
+	function.get_return_type ().get_mappings ().get_hirid ());
     }
 
   std::vector<std::pair<HIR::Pattern *, TyTy::BaseType *> > params;
+  std::unique_ptr<HIR::IdentifierPattern> param_pattern = nullptr;
   for (auto &param : function.get_function_params ())
     {
       // get the name as well required for later on
-      auto param_tyty = TypeCheckType::Resolve (param.get_type ().get ());
+      auto param_tyty = TypeCheckType::Resolve (param.get_type ());
 
       // these are implicit mappings and not used
       auto crate_num = mappings.get_current_crate ();
@@ -142,13 +143,13 @@ TypeCheckTopLevelExternItem::visit (HIR::ExternalFunctionItem &function)
 				     mappings.get_next_hir_id (crate_num),
 				     UNKNOWN_LOCAL_DEFID);
 
-      HIR::IdentifierPattern *param_pattern
-	= new HIR::IdentifierPattern (mapping, param.get_param_name (),
-				      UNDEF_LOCATION, false, Mutability::Imm,
-				      std::unique_ptr<HIR::Pattern> (nullptr));
+      param_pattern = Rust::make_unique<HIR::IdentifierPattern> (
+	HIR::IdentifierPattern (mapping, param.get_param_name (),
+				UNDEF_LOCATION, false, Mutability::Imm,
+				std::unique_ptr<HIR::Pattern> (nullptr)));
 
       params.push_back (
-	std::pair<HIR::Pattern *, TyTy::BaseType *> (param_pattern,
+	std::pair<HIR::Pattern *, TyTy::BaseType *> (param_pattern.get (),
 						     param_tyty));
 
       context->insert_type (param.get_mappings (), param_tyty);
@@ -316,7 +317,7 @@ TypeCheckTopLevelExternItem::visit (HIR::ExternalTypeItem &type)
 }
 
 TypeCheckImplItem::TypeCheckImplItem (
-  HIR::ImplBlock *parent, TyTy::BaseType *self,
+  HIR::ImplBlock &parent, TyTy::BaseType *self,
   std::vector<TyTy::SubstitutionParamMapping> substitutions)
   : TypeCheckBase (), parent (parent), self (self),
     substitutions (substitutions)
@@ -324,20 +325,20 @@ TypeCheckImplItem::TypeCheckImplItem (
 
 TyTy::BaseType *
 TypeCheckImplItem::Resolve (
-  HIR::ImplBlock *parent, HIR::ImplItem *item, TyTy::BaseType *self,
+  HIR::ImplBlock &parent, HIR::ImplItem &item, TyTy::BaseType *self,
   std::vector<TyTy::SubstitutionParamMapping> substitutions)
 {
   // is it already resolved?
   auto context = TypeCheckContext::get ();
   TyTy::BaseType *resolved = nullptr;
   bool already_resolved
-    = context->lookup_type (item->get_impl_mappings ().get_hirid (), &resolved);
+    = context->lookup_type (item.get_impl_mappings ().get_hirid (), &resolved);
   if (already_resolved)
     return resolved;
 
   // resolve
   TypeCheckImplItem resolver (parent, self, substitutions);
-  item->accept_vis (resolver);
+  item.accept_vis (resolver);
   return resolver.result;
 }
 
@@ -361,8 +362,7 @@ TypeCheckImplItem::visit (HIR::Function &function)
     ret_type = TyTy::TupleType::get_unit_type ();
   else
     {
-      auto resolved
-	= TypeCheckType::Resolve (function.get_return_type ().get ());
+      auto resolved = TypeCheckType::Resolve (function.get_return_type ());
       if (resolved == nullptr)
 	{
 	  rust_error_at (function.get_locus (),
@@ -372,10 +372,11 @@ TypeCheckImplItem::visit (HIR::Function &function)
 
       ret_type = resolved->clone ();
       ret_type->set_ref (
-	function.get_return_type ()->get_mappings ().get_hirid ());
+	function.get_return_type ().get_mappings ().get_hirid ());
     }
 
   std::vector<std::pair<HIR::Pattern *, TyTy::BaseType *> > params;
+  std::unique_ptr<HIR::IdentifierPattern> self_pattern = nullptr;
   if (function.is_method ())
     {
       // these are implicit mappings and not used
@@ -389,16 +390,17 @@ TypeCheckImplItem::visit (HIR::Function &function)
       // reuse the HIR identifier pattern which requires it
       HIR::SelfParam &self_param = function.get_self_param ();
       // FIXME: which location should be used for Rust::Identifier for `self`?
-      HIR::IdentifierPattern *self_pattern = new HIR::IdentifierPattern (
-	mapping, {"self"}, self_param.get_locus (), self_param.is_ref (),
-	self_param.get_mut (), std::unique_ptr<HIR::Pattern> (nullptr));
+      self_pattern = Rust::make_unique<HIR::IdentifierPattern> (
+	HIR::IdentifierPattern (mapping, {"self"}, self_param.get_locus (),
+				self_param.is_ref (), self_param.get_mut (),
+				std::unique_ptr<HIR::Pattern> (nullptr)));
 
       // might have a specified type
       TyTy::BaseType *self_type = nullptr;
       if (self_param.has_type ())
 	{
-	  std::unique_ptr<HIR::Type> &specified_type = self_param.get_type ();
-	  self_type = TypeCheckType::Resolve (specified_type.get ());
+	  auto &specified_type = self_param.get_type ();
+	  self_type = TypeCheckType::Resolve (specified_type);
 	}
       else
 	{
@@ -449,18 +451,21 @@ TypeCheckImplItem::visit (HIR::Function &function)
 
       context->insert_type (self_param.get_mappings (), self_type);
       params.push_back (
-	std::pair<HIR::Pattern *, TyTy::BaseType *> (self_pattern, self_type));
+	std::pair<HIR::Pattern *, TyTy::BaseType *> (self_pattern.get (),
+						     self_type));
     }
 
   for (auto &param : function.get_function_params ())
     {
       // get the name as well required for later on
-      auto param_tyty = TypeCheckType::Resolve (param.get_type ().get ());
-      params.push_back (std::pair<HIR::Pattern *, TyTy::BaseType *> (
-	param.get_param_name ().get (), param_tyty));
+      auto param_tyty = TypeCheckType::Resolve (param.get_type ());
 
       context->insert_type (param.get_mappings (), param_tyty);
-      TypeCheckPattern::Resolve (param.get_param_name ().get (), param_tyty);
+      TypeCheckPattern::Resolve (param.get_param_name (), param_tyty);
+
+      params.push_back (
+	std::pair<HIR::Pattern *, TyTy::BaseType *> (&param.get_param_name (),
+						     param_tyty));
     }
 
   tl::optional<CanonicalPath> canonical_path;
@@ -502,17 +507,16 @@ TypeCheckImplItem::visit (HIR::Function &function)
   context->push_return_type (TypeCheckContextItem (parent, &function),
 			     expected_ret_tyty);
 
-  auto block_expr_ty
-    = TypeCheckExpr::Resolve (function.get_definition ().get ());
+  auto block_expr_ty = TypeCheckExpr::Resolve (function.get_definition ());
 
   location_t fn_return_locus = function.has_function_return_type ()
-				 ? function.get_return_type ()->get_locus ()
+				 ? function.get_return_type ().get_locus ()
 				 : function.get_locus ();
 
-  coercion_site (function.get_definition ()->get_mappings ().get_hirid (),
+  coercion_site (function.get_definition ().get_mappings ().get_hirid (),
 		 TyTy::TyWithLocation (expected_ret_tyty, fn_return_locus),
 		 TyTy::TyWithLocation (block_expr_ty),
-		 function.get_definition ()->get_locus ());
+		 function.get_definition ().get_locus ());
 
   context->pop_return_type ();
 }
@@ -520,14 +524,13 @@ TypeCheckImplItem::visit (HIR::Function &function)
 void
 TypeCheckImplItem::visit (HIR::ConstantItem &constant)
 {
-  TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ().get ());
-  TyTy::BaseType *expr_type
-    = TypeCheckExpr::Resolve (constant.get_expr ().get ());
+  TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
+  TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (constant.get_expr ());
 
   TyTy::BaseType *unified = unify_site (
     constant.get_mappings ().get_hirid (),
-    TyTy::TyWithLocation (type, constant.get_type ()->get_locus ()),
-    TyTy::TyWithLocation (expr_type, constant.get_expr ()->get_locus ()),
+    TyTy::TyWithLocation (type, constant.get_type ().get_locus ()),
+    TyTy::TyWithLocation (expr_type, constant.get_expr ().get_locus ()),
     constant.get_locus ());
   context->insert_type (constant.get_mappings (), unified);
   result = unified;
@@ -542,7 +545,7 @@ TypeCheckImplItem::visit (HIR::TypeAlias &alias)
     resolve_generic_params (alias.get_generic_params (), substitutions);
 
   TyTy::BaseType *actual_type
-    = TypeCheckType::Resolve (alias.get_type_aliased ().get ());
+    = TypeCheckType::Resolve (alias.get_type_aliased ());
 
   context->insert_type (alias.get_mappings (), actual_type);
   result = actual_type;
@@ -555,7 +558,7 @@ TypeCheckImplItem::visit (HIR::TypeAlias &alias)
 }
 
 TypeCheckImplItemWithTrait::TypeCheckImplItemWithTrait (
-  HIR::ImplBlock *parent, TyTy::BaseType *self,
+  HIR::ImplBlock &parent, TyTy::BaseType *self,
   TyTy::TypeBoundPredicate &trait_reference,
   std::vector<TyTy::SubstitutionParamMapping> substitutions)
   : TypeCheckBase (), trait_reference (trait_reference),
@@ -567,13 +570,13 @@ TypeCheckImplItemWithTrait::TypeCheckImplItemWithTrait (
 
 TyTy::TypeBoundPredicateItem
 TypeCheckImplItemWithTrait::Resolve (
-  HIR::ImplBlock *parent, HIR::ImplItem *item, TyTy::BaseType *self,
+  HIR::ImplBlock &parent, HIR::ImplItem &item, TyTy::BaseType *self,
   TyTy::TypeBoundPredicate &trait_reference,
   std::vector<TyTy::SubstitutionParamMapping> substitutions)
 {
   TypeCheckImplItemWithTrait resolver (parent, self, trait_reference,
 				       substitutions);
-  item->accept_vis (resolver);
+  item.accept_vis (resolver);
   return resolver.resolved_trait_item;
 }
 
@@ -582,7 +585,7 @@ TypeCheckImplItemWithTrait::visit (HIR::ConstantItem &constant)
 {
   // normal resolution of the item
   TyTy::BaseType *lookup
-    = TypeCheckImplItem::Resolve (parent, &constant, self, substitutions);
+    = TypeCheckImplItem::Resolve (parent, constant, self, substitutions);
 
   // map the impl item to the associated trait item
   const auto tref = trait_reference.get ();
@@ -635,7 +638,7 @@ TypeCheckImplItemWithTrait::visit (HIR::TypeAlias &type)
 {
   // normal resolution of the item
   TyTy::BaseType *lookup
-    = TypeCheckImplItem::Resolve (parent, &type, self, substitutions);
+    = TypeCheckImplItem::Resolve (parent, type, self, substitutions);
 
   // map the impl item to the associated trait item
   const auto tref = trait_reference.get ();
@@ -696,7 +699,7 @@ TypeCheckImplItemWithTrait::visit (HIR::Function &function)
 {
   // normal resolution of the item
   TyTy::BaseType *lookup
-    = TypeCheckImplItem::Resolve (parent, &function, self, substitutions);
+    = TypeCheckImplItem::Resolve (parent, function, self, substitutions);
 
   // map the impl item to the associated trait item
   const auto tref = trait_reference.get ();
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.h b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
index 4fb2256c6b43..14f6a05a00fb 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
@@ -29,7 +29,7 @@ class TypeCheckTopLevelExternItem : public TypeCheckBase,
 				    public HIR::HIRExternalItemVisitor
 {
 public:
-  static TyTy::BaseType *Resolve (HIR::ExternalItem *item,
+  static TyTy::BaseType *Resolve (HIR::ExternalItem &item,
 				  const HIR::ExternBlock &parent);
 
   void visit (HIR::ExternalStaticItem &item) override;
@@ -47,7 +47,7 @@ class TypeCheckImplItem : public TypeCheckBase, public HIR::HIRImplVisitor
 {
 public:
   static TyTy::BaseType *
-  Resolve (HIR::ImplBlock *parent, HIR::ImplItem *item, TyTy::BaseType *self,
+  Resolve (HIR::ImplBlock &parent, HIR::ImplItem &item, TyTy::BaseType *self,
 	   std::vector<TyTy::SubstitutionParamMapping> substitutions);
 
   void visit (HIR::Function &function) override;
@@ -55,10 +55,10 @@ public:
   void visit (HIR::TypeAlias &type_alias) override;
 
 protected:
-  TypeCheckImplItem (HIR::ImplBlock *parent, TyTy::BaseType *self,
+  TypeCheckImplItem (HIR::ImplBlock &parent, TyTy::BaseType *self,
 		     std::vector<TyTy::SubstitutionParamMapping> substitutions);
 
-  HIR::ImplBlock *parent;
+  HIR::ImplBlock &parent;
   TyTy::BaseType *self;
   std::vector<TyTy::SubstitutionParamMapping> substitutions;
 
@@ -70,7 +70,7 @@ class TypeCheckImplItemWithTrait : public TypeCheckBase,
 {
 public:
   static TyTy::TypeBoundPredicateItem
-  Resolve (HIR::ImplBlock *parent, HIR::ImplItem *item, TyTy::BaseType *self,
+  Resolve (HIR::ImplBlock &parent, HIR::ImplItem &item, TyTy::BaseType *self,
 	   TyTy::TypeBoundPredicate &trait_reference,
 	   std::vector<TyTy::SubstitutionParamMapping> substitutions);
 
@@ -86,7 +86,7 @@ protected:
 
 private:
   TypeCheckImplItemWithTrait (
-    HIR::ImplBlock *parent, TyTy::BaseType *self,
+    HIR::ImplBlock &parent, TyTy::BaseType *self,
     TyTy::TypeBoundPredicate &trait_reference,
     std::vector<TyTy::SubstitutionParamMapping> substitutions);
 
@@ -95,7 +95,7 @@ private:
   TyTy::TypeBoundPredicate &trait_reference;
   TyTy::TypeBoundPredicateItem resolved_trait_item;
 
-  HIR::ImplBlock *parent;
+  HIR::ImplBlock &parent;
   TyTy::BaseType *self;
   std::vector<TyTy::SubstitutionParamMapping> substitutions;
   TyTy::RegionConstraints region_constraints;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index 0652777c8c62..e84ae333071e 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -150,7 +150,7 @@ void
 TypeCheckItem::visit (HIR::TypeAlias &alias)
 {
   TyTy::BaseType *actual_type
-    = TypeCheckType::Resolve (alias.get_type_aliased ().get ());
+    = TypeCheckType::Resolve (alias.get_type_aliased ());
 
   context->insert_type (alias.get_mappings (), actual_type);
 
@@ -182,7 +182,7 @@ TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
   for (auto &field : struct_decl.get_fields ())
     {
       TyTy::BaseType *field_type
-	= TypeCheckType::Resolve (field.get_field_type ().get ());
+	= TypeCheckType::Resolve (field.get_field_type ());
       auto *ty_field
 	= new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
 				     std::to_string (idx), field_type,
@@ -265,7 +265,7 @@ TypeCheckItem::visit (HIR::StructStruct &struct_decl)
   for (auto &field : struct_decl.get_fields ())
     {
       TyTy::BaseType *field_type
-	= TypeCheckType::Resolve (field.get_field_type ().get ());
+	= TypeCheckType::Resolve (field.get_field_type ());
       auto *ty_field
 	= new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
 				     field.get_field_name ().as_string (),
@@ -341,7 +341,7 @@ TypeCheckItem::visit (HIR::Enum &enum_decl)
   for (auto &variant : enum_decl.get_variants ())
     {
       TyTy::VariantDef *field_type
-	= TypeCheckEnumItem::Resolve (variant.get (), discriminant_value);
+	= TypeCheckEnumItem::Resolve (*variant, discriminant_value);
 
       discriminant_value++;
       variants.push_back (field_type);
@@ -400,7 +400,7 @@ TypeCheckItem::visit (HIR::Union &union_decl)
   for (auto &variant : union_decl.get_variants ())
     {
       TyTy::BaseType *variant_type
-	= TypeCheckType::Resolve (variant.get_field_type ().get ());
+	= TypeCheckType::Resolve (variant.get_field_type ());
       auto *ty_variant
 	= new TyTy::StructFieldType (variant.get_mappings ().get_hirid (),
 				     variant.get_field_name ().as_string (),
@@ -456,14 +456,14 @@ TypeCheckItem::visit (HIR::Union &union_decl)
 void
 TypeCheckItem::visit (HIR::StaticItem &var)
 {
-  TyTy::BaseType *type = TypeCheckType::Resolve (var.get_type ().get ());
-  TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (var.get_expr ().get ());
+  TyTy::BaseType *type = TypeCheckType::Resolve (var.get_type ());
+  TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (var.get_expr ());
 
   TyTy::BaseType *unified
     = coercion_site (var.get_mappings ().get_hirid (),
-		     TyTy::TyWithLocation (type, var.get_type ()->get_locus ()),
+		     TyTy::TyWithLocation (type, var.get_type ().get_locus ()),
 		     TyTy::TyWithLocation (expr_type,
-					   var.get_expr ()->get_locus ()),
+					   var.get_expr ().get_locus ()),
 		     var.get_locus ());
   context->insert_type (var.get_mappings (), unified);
   infered = unified;
@@ -472,14 +472,13 @@ TypeCheckItem::visit (HIR::StaticItem &var)
 void
 TypeCheckItem::visit (HIR::ConstantItem &constant)
 {
-  TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ().get ());
-  TyTy::BaseType *expr_type
-    = TypeCheckExpr::Resolve (constant.get_expr ().get ());
+  TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
+  TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (constant.get_expr ());
 
   TyTy::BaseType *unified = unify_site (
     constant.get_mappings ().get_hirid (),
-    TyTy::TyWithLocation (type, constant.get_type ()->get_locus ()),
-    TyTy::TyWithLocation (expr_type, constant.get_expr ()->get_locus ()),
+    TyTy::TyWithLocation (type, constant.get_type ().get_locus ()),
+    TyTy::TyWithLocation (expr_type, constant.get_expr ().get_locus ()),
     constant.get_locus ());
   context->insert_type (constant.get_mappings (), unified);
   infered = unified;
@@ -493,8 +492,8 @@ TypeCheckItem::visit (HIR::ImplBlock &impl_block)
   TraitReference *trait_reference = &TraitReference::error_node ();
   if (impl_block.has_trait_ref ())
     {
-      std::unique_ptr<HIR::TypePath> &ref = impl_block.get_trait_ref ();
-      trait_reference = TraitResolver::Resolve (*ref);
+      HIR::TypePath &ref = impl_block.get_trait_ref ();
+      trait_reference = TraitResolver::Resolve (ref);
       if (trait_reference->is_error ())
 	return;
     }
@@ -515,8 +514,7 @@ TypeCheckItem::visit (HIR::ImplBlock &impl_block)
   // resolve each impl_item
   for (auto &impl_item : impl_block.get_impl_items ())
     {
-      TypeCheckImplItem::Resolve (&impl_block, impl_item.get (), self,
-				  substitutions);
+      TypeCheckImplItem::Resolve (impl_block, *impl_item, self, substitutions);
     }
 
   // validate the impl items
@@ -540,7 +538,7 @@ TypeCheckItem::resolve_impl_item (HIR::ImplBlock &impl_block,
 
   TyTy::BaseType *self = resolve_impl_block_self (impl_block);
 
-  return TypeCheckImplItem::Resolve (&impl_block, &item, self, substitutions);
+  return TypeCheckImplItem::Resolve (impl_block, item, self, substitutions);
 }
 
 void
@@ -563,8 +561,7 @@ TypeCheckItem::visit (HIR::Function &function)
     ret_type = TyTy::TupleType::get_unit_type ();
   else
     {
-      auto resolved
-	= TypeCheckType::Resolve (function.get_return_type ().get ());
+      auto resolved = TypeCheckType::Resolve (function.get_return_type ());
       if (resolved->get_kind () == TyTy::TypeKind::ERROR)
 	{
 	  rust_error_at (function.get_locus (),
@@ -574,18 +571,18 @@ TypeCheckItem::visit (HIR::Function &function)
 
       ret_type = resolved->clone ();
       ret_type->set_ref (
-	function.get_return_type ()->get_mappings ().get_hirid ());
+	function.get_return_type ().get_mappings ().get_hirid ());
     }
 
   std::vector<std::pair<HIR::Pattern *, TyTy::BaseType *>> params;
   for (auto &param : function.get_function_params ())
     {
       // get the name as well required for later on
-      auto param_tyty = TypeCheckType::Resolve (param.get_type ().get ());
-      params.emplace_back (param.get_param_name ().get (), param_tyty);
+      auto param_tyty = TypeCheckType::Resolve (param.get_type ());
+      params.emplace_back (&param.get_param_name (), param_tyty);
 
       context->insert_type (param.get_mappings (), param_tyty);
-      TypeCheckPattern::Resolve (param.get_param_name ().get (), param_tyty);
+      TypeCheckPattern::Resolve (param.get_param_name (), param_tyty);
     }
 
   auto path = CanonicalPath::create_empty ();
@@ -628,16 +625,15 @@ TypeCheckItem::visit (HIR::Function &function)
 			     expected_ret_tyty);
 
   context->switch_to_fn_body ();
-  auto block_expr_ty
-    = TypeCheckExpr::Resolve (function.get_definition ().get ());
+  auto block_expr_ty = TypeCheckExpr::Resolve (function.get_definition ());
 
   location_t fn_return_locus = function.has_function_return_type ()
-				 ? function.get_return_type ()->get_locus ()
+				 ? function.get_return_type ().get_locus ()
 				 : function.get_locus ();
-  coercion_site (function.get_definition ()->get_mappings ().get_hirid (),
+  coercion_site (function.get_definition ().get_mappings ().get_hirid (),
 		 TyTy::TyWithLocation (expected_ret_tyty, fn_return_locus),
 		 TyTy::TyWithLocation (block_expr_ty),
-		 function.get_definition ()->get_locus ());
+		 function.get_definition ().get_locus ());
 
   context->pop_return_type ();
 
@@ -691,7 +687,7 @@ TypeCheckItem::visit (HIR::ExternBlock &extern_block)
 {
   for (auto &item : extern_block.get_extern_items ())
     {
-      TypeCheckTopLevelExternItem::Resolve (item.get (), extern_block);
+      TypeCheckTopLevelExternItem::Resolve (*item, extern_block);
     }
 }
 
@@ -713,17 +709,17 @@ TypeCheckItem::resolve_impl_block_substitutions (HIR::ImplBlock &impl_block,
   TraitReference *trait_reference = &TraitReference::error_node ();
   if (impl_block.has_trait_ref ())
     {
-      std::unique_ptr<HIR::TypePath> &ref = impl_block.get_trait_ref ();
-      trait_reference = TraitResolver::Resolve (*ref);
+      auto &ref = impl_block.get_trait_ref ();
+      trait_reference = TraitResolver::Resolve (ref);
       rust_assert (!trait_reference->is_error ());
 
       // we don't error out here see: gcc/testsuite/rust/compile/traits2.rs
       // for example
-      specified_bound
-	= get_predicate_from_bound (*ref, impl_block.get_type ().get ());
+      specified_bound = get_predicate_from_bound (ref, impl_block.get_type ());
     }
 
-  TyTy::BaseType *self = TypeCheckType::Resolve (impl_block.get_type ().get ());
+  TyTy::BaseType *self = TypeCheckType::Resolve (impl_block.get_type ());
+
   if (self->is<TyTy::ErrorType> ())
     {
       // we cannot check for unconstrained type arguments when the Self type is
@@ -758,14 +754,14 @@ TypeCheckItem::validate_trait_impl_block (
   auto specified_bound = TyTy::TypeBoundPredicate::error ();
   if (impl_block.has_trait_ref ())
     {
-      std::unique_ptr<HIR::TypePath> &ref = impl_block.get_trait_ref ();
+      auto &ref = impl_block.get_trait_ref ();
+      trait_reference = TraitResolver::Resolve (ref);
       if (trait_reference->is_error ())
 	return;
 
       // we don't error out here see: gcc/testsuite/rust/compile/traits2.rs
       // for example
-      specified_bound
-	= get_predicate_from_bound (*ref, impl_block.get_type ().get ());
+      specified_bound = get_predicate_from_bound (ref, impl_block.get_type ());
     }
 
   bool is_trait_impl_block = !trait_reference->is_error ();
@@ -775,8 +771,7 @@ TypeCheckItem::validate_trait_impl_block (
       if (!specified_bound.is_error ())
 	{
 	  auto trait_item_ref
-	    = TypeCheckImplItemWithTrait::Resolve (&impl_block,
-						   impl_item.get (), self,
+	    = TypeCheckImplItemWithTrait::Resolve (impl_block, *impl_item, self,
 						   specified_bound,
 						   substitutions);
 	  if (!trait_item_ref.is_error ())
@@ -849,7 +844,7 @@ TypeCheckItem::validate_trait_impl_block (
 TyTy::BaseType *
 TypeCheckItem::resolve_impl_block_self (HIR::ImplBlock &impl_block)
 {
-  return TypeCheckType::Resolve (impl_block.get_type ().get ());
+  return TypeCheckType::Resolve (impl_block.get_type ());
 }
 
 } // namespace Resolver
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index 7b934b38eb37..cc79e4d49956 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -34,8 +34,7 @@ void
 TypeCheckExpr::visit (HIR::QualifiedPathInExpression &expr)
 {
   HIR::QualifiedPathType qual_path_type = expr.get_path_type ();
-  TyTy::BaseType *root
-    = TypeCheckType::Resolve (qual_path_type.get_type ().get ());
+  TyTy::BaseType *root = TypeCheckType::Resolve (qual_path_type.get_type ());
   if (root->get_kind () == TyTy::TypeKind::ERROR)
     return;
 
@@ -48,8 +47,8 @@ TypeCheckExpr::visit (HIR::QualifiedPathInExpression &expr)
     }
 
   // Resolve the trait now
-  std::unique_ptr<HIR::TypePath> &trait_path_ref = qual_path_type.get_trait ();
-  TraitReference *trait_ref = TraitResolver::Resolve (*trait_path_ref.get ());
+  HIR::TypePath &trait_path_ref = qual_path_type.get_trait ();
+  TraitReference *trait_ref = TraitResolver::Resolve (trait_path_ref);
   if (trait_ref->is_error ())
     return;
 
@@ -64,8 +63,7 @@ TypeCheckExpr::visit (HIR::QualifiedPathInExpression &expr)
 
   // get the predicate for the bound
   auto specified_bound
-    = get_predicate_from_bound (*trait_path_ref.get (),
-				qual_path_type.get_type ().get ());
+    = get_predicate_from_bound (trait_path_ref, qual_path_type.get_type ());
   if (specified_bound.is_error ())
     return;
 
@@ -457,7 +455,7 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
 	    {
 	      // we need to setup with apropriate bounds
 	      HIR::TypePath &bound_path
-		= *associated->get_impl_block ()->get_trait_ref ().get ();
+		= associated->get_impl_block ()->get_trait_ref ();
 	      const auto &trait_ref = *TraitResolver::Resolve (bound_path);
 	      rust_assert (!trait_ref.is_error ());
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
index 88e4d32f6bc2..a118d1537f85 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
@@ -33,15 +33,15 @@ TypeCheckPattern::TypeCheckPattern (TyTy::BaseType *parent)
 {}
 
 TyTy::BaseType *
-TypeCheckPattern::Resolve (HIR::Pattern *pattern, TyTy::BaseType *parent)
+TypeCheckPattern::Resolve (HIR::Pattern &pattern, TyTy::BaseType *parent)
 {
   TypeCheckPattern resolver (parent);
-  pattern->accept_vis (resolver);
+  pattern.accept_vis (resolver);
 
   if (resolver.infered == nullptr)
-    return new TyTy::ErrorType (pattern->get_mappings ().get_hirid ());
+    return new TyTy::ErrorType (pattern.get_mappings ().get_hirid ());
 
-  resolver.context->insert_type (pattern->get_mappings (), resolver.infered);
+  resolver.context->insert_type (pattern.get_mappings (), resolver.infered);
   return resolver.infered;
 }
 
@@ -49,7 +49,7 @@ void
 TypeCheckPattern::visit (HIR::PathInExpression &pattern)
 {
   // Pattern must be enum variants, sturcts, constants, or associated constansts
-  TyTy::BaseType *pattern_ty = TypeCheckExpr::Resolve (&pattern);
+  TyTy::BaseType *pattern_ty = TypeCheckExpr::Resolve (pattern);
 
   NodeId ref_node_id = UNKNOWN_NODEID;
   bool maybe_item = false;
@@ -161,7 +161,7 @@ TypeCheckPattern::visit (HIR::PathInExpression &pattern)
 void
 TypeCheckPattern::visit (HIR::TupleStructPattern &pattern)
 {
-  TyTy::BaseType *pattern_ty = TypeCheckExpr::Resolve (&pattern.get_path ());
+  TyTy::BaseType *pattern_ty = TypeCheckExpr::Resolve (pattern.get_path ());
   if (pattern_ty->get_kind () != TyTy::TypeKind::ADT)
     {
       rust_error_at (
@@ -210,8 +210,8 @@ TypeCheckPattern::visit (HIR::TupleStructPattern &pattern)
   // error[E0023]: this pattern has 0 fields, but the corresponding tuple
   // variant has 1 field
 
-  std::unique_ptr<HIR::TupleStructItems> &items = pattern.get_items ();
-  switch (items->get_item_type ())
+  auto &items = pattern.get_items ();
+  switch (items.get_item_type ())
     {
       case HIR::TupleStructItems::RANGED: {
 	// TODO
@@ -221,7 +221,7 @@ TypeCheckPattern::visit (HIR::TupleStructPattern &pattern)
 
       case HIR::TupleStructItems::MULTIPLE: {
 	HIR::TupleStructItemsNoRange &items_no_range
-	  = static_cast<HIR::TupleStructItemsNoRange &> (*items.get ());
+	  = static_cast<HIR::TupleStructItemsNoRange &> (items);
 
 	if (items_no_range.get_patterns ().size () != variant->num_fields ())
 	  {
@@ -247,7 +247,7 @@ TypeCheckPattern::visit (HIR::TupleStructPattern &pattern)
 
 	    // setup the type on this pattern type
 	    context->insert_type (pattern->get_mappings (), fty);
-	    TypeCheckPattern::Resolve (pattern.get (), fty);
+	    TypeCheckPattern::Resolve (*pattern, fty);
 	  }
       }
       break;
@@ -266,7 +266,7 @@ emit_invalid_field_error (location_t loc, Rust::TyTy::VariantDef *variant,
 void
 TypeCheckPattern::visit (HIR::StructPattern &pattern)
 {
-  TyTy::BaseType *pattern_ty = TypeCheckExpr::Resolve (&pattern.get_path ());
+  TyTy::BaseType *pattern_ty = TypeCheckExpr::Resolve (pattern.get_path ());
   if (pattern_ty->get_kind () != TyTy::TypeKind::ADT)
     {
       rust_error_at (pattern.get_locus (),
@@ -324,7 +324,7 @@ TypeCheckPattern::visit (HIR::StructPattern &pattern)
 
 	  case HIR::StructPatternField::ItemType::IDENT_PAT: {
 	    HIR::StructPatternFieldIdentPat &ident
-	      = static_cast<HIR::StructPatternFieldIdentPat &> (*field.get ());
+	      = static_cast<HIR::StructPatternFieldIdentPat &> (*field);
 
 	    TyTy::StructFieldType *field = nullptr;
 	    if (!variant->lookup_field (ident.get_identifier ().as_string (),
@@ -337,13 +337,13 @@ TypeCheckPattern::visit (HIR::StructPattern &pattern)
 	    named_fields.push_back (ident.get_identifier ().as_string ());
 
 	    TyTy::BaseType *fty = field->get_field_type ();
-	    TypeCheckPattern::Resolve (ident.get_pattern ().get (), fty);
+	    TypeCheckPattern::Resolve (ident.get_pattern (), fty);
 	  }
 	  break;
 
 	  case HIR::StructPatternField::ItemType::IDENT: {
 	    HIR::StructPatternFieldIdent &ident
-	      = static_cast<HIR::StructPatternFieldIdent &> (*field.get ());
+	      = static_cast<HIR::StructPatternFieldIdent &> (*field);
 
 	    TyTy::StructFieldType *field = nullptr;
 	    if (!variant->lookup_field (ident.get_identifier ().as_string (),
@@ -440,12 +440,11 @@ void
 TypeCheckPattern::visit (HIR::TuplePattern &pattern)
 {
   std::unique_ptr<HIR::TuplePatternItems> items;
-  switch (pattern.get_items ()->get_item_type ())
+  switch (pattern.get_items ().get_item_type ())
     {
       case HIR::TuplePatternItems::ItemType::MULTIPLE: {
-	HIR::TuplePatternItemsMultiple &ref
-	  = *static_cast<HIR::TuplePatternItemsMultiple *> (
-	    pattern.get_items ().get ());
+	auto &ref = static_cast<HIR::TuplePatternItemsMultiple &> (
+	  pattern.get_items ());
 
 	auto resolved_parent = parent->destructure ();
 	if (resolved_parent->get_kind () != TyTy::TUPLE)
@@ -474,8 +473,7 @@ TypeCheckPattern::visit (HIR::TuplePattern &pattern)
 	    auto &p = patterns[i];
 	    TyTy::BaseType *par_type = par.get_field (i);
 
-	    TyTy::BaseType *elem
-	      = TypeCheckPattern::Resolve (p.get (), par_type);
+	    TyTy::BaseType *elem = TypeCheckPattern::Resolve (*p, par_type);
 	    pattern_elems.push_back (TyTy::TyVar (elem->get_ref ()));
 	  }
 	infered = new TyTy::TupleType (pattern.get_mappings ().get_hirid (),
@@ -543,10 +541,10 @@ TypeCheckPattern::visit (HIR::ReferencePattern &pattern)
       return;
     }
 
-  TyTy::ReferenceType *ref_ty_ty = static_cast<TyTy::ReferenceType *> (parent);
+  auto &ref_ty_ty = static_cast<TyTy::ReferenceType &> (*parent);
   TyTy::BaseType *infered_base
-    = TypeCheckPattern::Resolve (pattern.get_referenced_pattern ().get (),
-				 ref_ty_ty->get_base ());
+    = TypeCheckPattern::Resolve (pattern.get_referenced_pattern (),
+				 ref_ty_ty.get_base ());
   infered = new TyTy::ReferenceType (pattern.get_mappings ().get_hirid (),
 				     TyTy::TyVar (infered_base->get_ref ()),
 				     pattern.is_mut () ? Mutability::Mut
@@ -578,15 +576,14 @@ TypeCheckPattern::emit_pattern_size_error (const HIR::Pattern &pattern,
 
 TyTy::BaseType *
 TypeCheckPattern::typecheck_range_pattern_bound (
-  std::unique_ptr<Rust::HIR::RangePatternBound> &bound,
-  Analysis::NodeMapping mappings, location_t locus)
+  Rust::HIR::RangePatternBound &bound, Analysis::NodeMapping mappings,
+  location_t locus)
 {
   TyTy::BaseType *resolved_bound = nullptr;
-  switch (bound->get_bound_type ())
+  switch (bound.get_bound_type ())
     {
       case HIR::RangePatternBound::RangePatternBoundType::LITERAL: {
-	HIR::RangePatternBoundLiteral &ref
-	  = *static_cast<HIR::RangePatternBoundLiteral *> (bound.get ());
+	auto &ref = static_cast<HIR::RangePatternBoundLiteral &> (bound);
 
 	HIR::Literal lit = ref.get_literal ();
 
@@ -595,18 +592,16 @@ TypeCheckPattern::typecheck_range_pattern_bound (
       break;
 
       case HIR::RangePatternBound::RangePatternBoundType::PATH: {
-	HIR::RangePatternBoundPath &ref
-	  = *static_cast<HIR::RangePatternBoundPath *> (bound.get ());
+	auto &ref = static_cast<HIR::RangePatternBoundPath &> (bound);
 
-	resolved_bound = TypeCheckExpr::Resolve (&ref.get_path ());
+	resolved_bound = TypeCheckExpr::Resolve (ref.get_path ());
       }
       break;
 
       case HIR::RangePatternBound::RangePatternBoundType::QUALPATH: {
-	HIR::RangePatternBoundQualPath &ref
-	  = *static_cast<HIR::RangePatternBoundQualPath *> (bound.get ());
+	auto &ref = static_cast<HIR::RangePatternBoundQualPath &> (bound);
 
-	resolved_bound = TypeCheckExpr::Resolve (&ref.get_qualified_path ());
+	resolved_bound = TypeCheckExpr::Resolve (ref.get_qualified_path ());
       }
       break;
     }
@@ -623,7 +618,7 @@ TypeCheckPattern::visit (HIR::AltPattern &pattern)
   std::vector<TyTy::BaseType *> types;
   for (auto &alt_pattern : alts)
     {
-      types.push_back (TypeCheckPattern::Resolve (alt_pattern.get (), parent));
+      types.push_back (TypeCheckPattern::Resolve (*alt_pattern, parent));
     }
 
   TyTy::BaseType *alt_pattern_type
@@ -642,16 +637,16 @@ TypeCheckPattern::visit (HIR::AltPattern &pattern)
 }
 
 TyTy::BaseType *
-ClosureParamInfer::Resolve (HIR::Pattern *pattern)
+ClosureParamInfer::Resolve (HIR::Pattern &pattern)
 {
   ClosureParamInfer resolver;
-  pattern->accept_vis (resolver);
+  pattern.accept_vis (resolver);
 
   if (resolver.infered->get_kind () != TyTy::TypeKind::ERROR)
     {
       resolver.context->insert_implicit_type (resolver.infered);
       resolver.mappings.insert_location (resolver.infered->get_ref (),
-					 pattern->get_locus ());
+					 pattern.get_locus ());
     }
   return resolver.infered;
 }
@@ -682,7 +677,7 @@ void
 ClosureParamInfer::visit (HIR::ReferencePattern &pattern)
 {
   TyTy::BaseType *element
-    = ClosureParamInfer::Resolve (pattern.get_referenced_pattern ().get ());
+    = ClosureParamInfer::Resolve (pattern.get_referenced_pattern ());
 
   HirId id = pattern.get_mappings ().get_hirid ();
   infered = new TyTy::ReferenceType (id, TyTy::TyVar (element->get_ref ()),
diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.h b/gcc/rust/typecheck/rust-hir-type-check-pattern.h
index ba45b65b340a..d477181360a9 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.h
@@ -28,7 +28,7 @@ namespace Resolver {
 class TypeCheckPattern : public TypeCheckBase, public HIR::HIRPatternVisitor
 {
 public:
-  static TyTy::BaseType *Resolve (HIR::Pattern *pattern,
+  static TyTy::BaseType *Resolve (HIR::Pattern &pattern,
 				  TyTy::BaseType *parent);
 
   void visit (HIR::PathInExpression &pattern) override;
@@ -47,9 +47,10 @@ public:
 private:
   TypeCheckPattern (TyTy::BaseType *parent);
 
-  TyTy::BaseType *typecheck_range_pattern_bound (
-    std::unique_ptr<Rust::HIR::RangePatternBound> &bound,
-    Analysis::NodeMapping mappings, location_t locus);
+  TyTy::BaseType *
+  typecheck_range_pattern_bound (Rust::HIR::RangePatternBound &bound,
+				 Analysis::NodeMapping mappings,
+				 location_t locus);
 
   void emit_pattern_size_error (const HIR::Pattern &pattern,
 				size_t expected_field_count,
@@ -62,7 +63,7 @@ private:
 class ClosureParamInfer : private TypeCheckBase, private HIR::HIRPatternVisitor
 {
 public:
-  static TyTy::BaseType *Resolve (HIR::Pattern *pattern);
+  static TyTy::BaseType *Resolve (HIR::Pattern &pattern);
 
   void visit (HIR::PathInExpression &pattern) override;
   void visit (HIR::StructPattern &pattern) override;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-stmt.cc b/gcc/rust/typecheck/rust-hir-type-check-stmt.cc
index c395ed02f889..4e53856278f1 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-stmt.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-stmt.cc
@@ -28,17 +28,17 @@ namespace Rust {
 namespace Resolver {
 
 TyTy::BaseType *
-TypeCheckStmt::Resolve (HIR::Stmt *stmt)
+TypeCheckStmt::Resolve (HIR::Stmt &stmt)
 {
   TypeCheckStmt resolver;
-  stmt->accept_vis (resolver);
+  stmt.accept_vis (resolver);
   return resolver.infered;
 }
 
 void
 TypeCheckStmt::visit (HIR::ExprStmt &stmt)
 {
-  infered = TypeCheckExpr::Resolve (stmt.get_expr ().get ());
+  infered = TypeCheckExpr::Resolve (stmt.get_expr ());
 }
 
 void
@@ -52,21 +52,20 @@ TypeCheckStmt::visit (HIR::ExternBlock &extern_block)
 {
   for (auto &item : extern_block.get_extern_items ())
     {
-      TypeCheckTopLevelExternItem::Resolve (item.get (), extern_block);
+      TypeCheckTopLevelExternItem::Resolve (*item, extern_block);
     }
 }
 
 void
 TypeCheckStmt::visit (HIR::ConstantItem &constant)
 {
-  TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ().get ());
-  TyTy::BaseType *expr_type
-    = TypeCheckExpr::Resolve (constant.get_expr ().get ());
+  TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
+  TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (constant.get_expr ());
 
   infered = coercion_site (
     constant.get_mappings ().get_hirid (),
-    TyTy::TyWithLocation (type, constant.get_type ()->get_locus ()),
-    TyTy::TyWithLocation (expr_type, constant.get_expr ()->get_locus ()),
+    TyTy::TyWithLocation (type, constant.get_type ().get_locus ()),
+    TyTy::TyWithLocation (expr_type, constant.get_expr ().get_locus ()),
     constant.get_locus ());
   context->insert_type (constant.get_mappings (), infered);
 }
@@ -76,13 +75,13 @@ TypeCheckStmt::visit (HIR::LetStmt &stmt)
 {
   infered = TyTy::TupleType::get_unit_type ();
 
-  HIR::Pattern &stmt_pattern = *stmt.get_pattern ();
+  auto &stmt_pattern = stmt.get_pattern ();
   TyTy::BaseType *init_expr_ty = nullptr;
   location_t init_expr_locus = UNKNOWN_LOCATION;
   if (stmt.has_init_expr ())
     {
-      init_expr_locus = stmt.get_init_expr ()->get_locus ();
-      init_expr_ty = TypeCheckExpr::Resolve (stmt.get_init_expr ().get ());
+      init_expr_locus = stmt.get_init_expr ().get_locus ();
+      init_expr_ty = TypeCheckExpr::Resolve (stmt.get_init_expr ());
       if (init_expr_ty->get_kind () == TyTy::TypeKind::ERROR)
 	return;
 
@@ -94,8 +93,8 @@ TypeCheckStmt::visit (HIR::LetStmt &stmt)
   location_t specified_ty_locus;
   if (stmt.has_type ())
     {
-      specified_ty = TypeCheckType::Resolve (stmt.get_type ().get ());
-      specified_ty_locus = stmt.get_type ()->get_locus ();
+      specified_ty = TypeCheckType::Resolve (stmt.get_type ());
+      specified_ty_locus = stmt.get_type ().get_locus ();
     }
 
   // let x:i32 = 123;
@@ -105,19 +104,19 @@ TypeCheckStmt::visit (HIR::LetStmt &stmt)
 		     TyTy::TyWithLocation (specified_ty, specified_ty_locus),
 		     TyTy::TyWithLocation (init_expr_ty, init_expr_locus),
 		     stmt.get_locus ());
-      TypeCheckPattern::Resolve (&stmt_pattern, specified_ty);
+      TypeCheckPattern::Resolve (stmt_pattern, specified_ty);
     }
   else
     {
       // let x:i32;
       if (specified_ty != nullptr)
 	{
-	  TypeCheckPattern::Resolve (&stmt_pattern, specified_ty);
+	  TypeCheckPattern::Resolve (stmt_pattern, specified_ty);
 	}
       // let x = 123;
       else if (init_expr_ty != nullptr)
 	{
-	  TypeCheckPattern::Resolve (&stmt_pattern, init_expr_ty);
+	  TypeCheckPattern::Resolve (stmt_pattern, init_expr_ty);
 	}
       // let x;
       else
@@ -127,7 +126,7 @@ TypeCheckStmt::visit (HIR::LetStmt &stmt)
 				   TyTy::InferType::InferTypeKind::GENERAL,
 				   TyTy::InferType::TypeHint::Default (),
 				   stmt.get_locus ());
-	  TypeCheckPattern::Resolve (&stmt_pattern, infer);
+	  TypeCheckPattern::Resolve (stmt_pattern, infer);
 	}
     }
 }
@@ -135,12 +134,12 @@ TypeCheckStmt::visit (HIR::LetStmt &stmt)
 void
 TypeCheckStmt::visit (HIR::TypePath &path)
 {
-  infered = TypeCheckType::Resolve (&path);
+  infered = TypeCheckType::Resolve (path);
 }
 void
 TypeCheckStmt::visit (HIR::QualifiedPathInType &path)
 {
-  infered = TypeCheckType::Resolve (&path);
+  infered = TypeCheckType::Resolve (path);
 }
 
 void
diff --git a/gcc/rust/typecheck/rust-hir-type-check-stmt.h b/gcc/rust/typecheck/rust-hir-type-check-stmt.h
index 6d9137257778..d6798058d471 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-stmt.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-stmt.h
@@ -28,7 +28,7 @@ namespace Resolver {
 class TypeCheckStmt : private TypeCheckBase, private HIR::HIRStmtVisitor
 {
 public:
-  static TyTy::BaseType *Resolve (HIR::Stmt *stmt);
+  static TyTy::BaseType *Resolve (HIR::Stmt &stmt);
 
   void visit (HIR::ExprStmt &stmt) override;
   void visit (HIR::EmptyStmt &stmt) override;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-struct-field.h b/gcc/rust/typecheck/rust-hir-type-check-struct-field.h
index cfa17acf6e9f..800f7ca43901 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-struct-field.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-struct-field.h
@@ -33,7 +33,7 @@ namespace Resolver {
 class TypeCheckStructExpr : public TypeCheckBase
 {
 public:
-  static TyTy::BaseType *Resolve (HIR::StructExprStructFields *expr);
+  static TyTy::BaseType *Resolve (HIR::StructExprStructFields &expr);
 
   // Helper for making any errors
   static Error
@@ -49,7 +49,7 @@ protected:
   bool visit (HIR::StructExprFieldIdentifier &field);
 
 private:
-  TypeCheckStructExpr (HIR::Expr *e);
+  TypeCheckStructExpr (HIR::Expr &e);
 
   // result
   TyTy::BaseType *resolved;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-struct.cc b/gcc/rust/typecheck/rust-hir-type-check-struct.cc
index 5018829ec7da..e19925a96ee8 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-struct.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-struct.cc
@@ -24,18 +24,18 @@
 namespace Rust {
 namespace Resolver {
 
-TypeCheckStructExpr::TypeCheckStructExpr (HIR::Expr *e)
+TypeCheckStructExpr::TypeCheckStructExpr (HIR::Expr &e)
   : TypeCheckBase (),
-    resolved (new TyTy::ErrorType (e->get_mappings ().get_hirid ())),
+    resolved (new TyTy::ErrorType (e.get_mappings ().get_hirid ())),
     struct_path_resolved (nullptr),
     variant (&TyTy::VariantDef::get_error_node ())
 {}
 
 TyTy::BaseType *
-TypeCheckStructExpr::Resolve (HIR::StructExprStructFields *expr)
+TypeCheckStructExpr::Resolve (HIR::StructExprStructFields &expr)
 {
   TypeCheckStructExpr resolver (expr);
-  resolver.resolve (*expr);
+  resolver.resolve (expr);
   return resolver.resolved;
 }
 
@@ -43,7 +43,7 @@ void
 TypeCheckStructExpr::resolve (HIR::StructExprStructFields &struct_expr)
 {
   TyTy::BaseType *struct_path_ty
-    = TypeCheckExpr::Resolve (&struct_expr.get_struct_name ());
+    = TypeCheckExpr::Resolve (struct_expr.get_struct_name ());
   if (struct_path_ty->get_kind () != TyTy::TypeKind::ADT)
     {
       rust_error_at (struct_expr.get_struct_name ().get_locus (),
@@ -56,7 +56,7 @@ TypeCheckStructExpr::resolve (HIR::StructExprStructFields &struct_expr)
   if (struct_expr.has_struct_base ())
     {
       TyTy::BaseType *base_resolved
-	= TypeCheckExpr::Resolve (struct_expr.struct_base->base_struct.get ());
+	= TypeCheckExpr::Resolve (*struct_expr.struct_base->base_struct);
       TyTy::BaseType *base_unify = unify_site (
 	struct_expr.struct_base->base_struct->get_mappings ().get_hirid (),
 	TyTy::TyWithLocation (struct_path_resolved),
@@ -284,8 +284,8 @@ TypeCheckStructExpr::visit (HIR::StructExprFieldIdentifierValue &field)
       return false;
     }
 
-  TyTy::BaseType *value = TypeCheckExpr::Resolve (field.get_value ().get ());
-  location_t value_locus = field.get_value ()->get_locus ();
+  TyTy::BaseType *value = TypeCheckExpr::Resolve (field.get_value ());
+  location_t value_locus = field.get_value ().get_locus ();
 
   HirId coercion_site_id = field.get_mappings ().get_hirid ();
   resolved_field_value_expr
@@ -330,8 +330,8 @@ TypeCheckStructExpr::visit (HIR::StructExprFieldIndexValue &field)
       return false;
     }
 
-  TyTy::BaseType *value = TypeCheckExpr::Resolve (field.get_value ().get ());
-  location_t value_locus = field.get_value ()->get_locus ();
+  TyTy::BaseType *value = TypeCheckExpr::Resolve (field.get_value ());
+  location_t value_locus = field.get_value ().get_locus ();
 
   HirId coercion_site_id = field.get_mappings ().get_hirid ();
   resolved_field_value_expr
@@ -385,7 +385,7 @@ TypeCheckStructExpr::visit (HIR::StructExprFieldIdentifier &field)
 			    HIR::GenericArgs::create_empty ());
   HIR::PathInExpression expr (mappings_copy2, {seg}, field.get_locus (), false,
 			      {});
-  TyTy::BaseType *value = TypeCheckExpr::Resolve (&expr);
+  TyTy::BaseType *value = TypeCheckExpr::Resolve (expr);
   location_t value_locus = expr.get_locus ();
 
   HirId coercion_site_id = field.get_mappings ().get_hirid ();
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index 0ff4ac45247a..089a5af121a0 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -18,6 +18,7 @@
 
 #include "rust-hir-type-check-type.h"
 #include "options.h"
+#include "optional.h"
 #include "rust-hir-trait-resolve.h"
 #include "rust-hir-type-check-expr.h"
 #include "rust-hir-path-probe.h"
@@ -26,18 +27,19 @@
 #include "rust-mapping-common.h"
 #include "rust-substitution-mapper.h"
 #include "rust-type-util.h"
+#include <functional>
 
 namespace Rust {
 namespace Resolver {
 
 HIR::GenericArgs
-TypeCheckResolveGenericArguments::resolve (HIR::TypePathSegment *segment)
+TypeCheckResolveGenericArguments::resolve (HIR::TypePathSegment &segment)
 {
-  TypeCheckResolveGenericArguments resolver (segment->get_locus ());
-  switch (segment->get_type ())
+  TypeCheckResolveGenericArguments resolver (segment.get_locus ());
+  switch (segment.get_type ())
     {
     case HIR::TypePathSegment::SegmentType::GENERIC:
-      resolver.visit (static_cast<HIR::TypePathSegmentGeneric &> (*segment));
+      resolver.visit (static_cast<HIR::TypePathSegmentGeneric &> (segment));
       break;
 
     default:
@@ -53,20 +55,20 @@ TypeCheckResolveGenericArguments::visit (HIR::TypePathSegmentGeneric &generic)
 }
 
 TyTy::BaseType *
-TypeCheckType::Resolve (HIR::Type *type)
+TypeCheckType::Resolve (HIR::Type &type)
 {
   // is it already resolved?
   auto context = TypeCheckContext::get ();
   TyTy::BaseType *resolved = nullptr;
   bool already_resolved
-    = context->lookup_type (type->get_mappings ().get_hirid (), &resolved);
+    = context->lookup_type (type.get_mappings ().get_hirid (), &resolved);
   if (already_resolved)
     return resolved;
 
-  TypeCheckType resolver (type->get_mappings ().get_hirid ());
-  type->accept_vis (resolver);
+  TypeCheckType resolver (type.get_mappings ().get_hirid ());
+  type.accept_vis (resolver);
   rust_assert (resolver.translated != nullptr);
-  resolver.context->insert_type (type->get_mappings (), resolver.translated);
+  resolver.context->insert_type (type.get_mappings (), resolver.translated);
   return resolver.translated;
 }
 
@@ -82,7 +84,7 @@ TypeCheckType::visit (HIR::BareFunctionType &fntype)
   TyTy::BaseType *return_type;
   if (fntype.has_return_type ())
     {
-      return_type = TypeCheckType::Resolve (fntype.get_return_type ().get ());
+      return_type = TypeCheckType::Resolve (fntype.get_return_type ());
     }
   else
     {
@@ -95,7 +97,7 @@ TypeCheckType::visit (HIR::BareFunctionType &fntype)
   std::vector<TyTy::TyVar> params;
   for (auto &param : fntype.get_function_params ())
     {
-      TyTy::BaseType *ptype = TypeCheckType::Resolve (param.get_type ().get ());
+      TyTy::BaseType *ptype = TypeCheckType::Resolve (param.get_type ());
       params.push_back (TyTy::TyVar (ptype->get_ref ()));
     }
 
@@ -121,7 +123,7 @@ TypeCheckType::visit (HIR::TupleType &tuple)
   std::vector<TyTy::TyVar> fields;
   for (auto &elem : tuple.get_elems ())
     {
-      auto field_ty = TypeCheckType::Resolve (elem.get ());
+      auto field_ty = TypeCheckType::Resolve (*elem);
       fields.push_back (TyTy::TyVar (field_ty->get_ref ()));
     }
 
@@ -163,8 +165,7 @@ void
 TypeCheckType::visit (HIR::QualifiedPathInType &path)
 {
   HIR::QualifiedPathType qual_path_type = path.get_path_type ();
-  TyTy::BaseType *root
-    = TypeCheckType::Resolve (qual_path_type.get_type ().get ());
+  TyTy::BaseType *root = TypeCheckType::Resolve (qual_path_type.get_type ());
   if (root->get_kind () == TyTy::TypeKind::ERROR)
     {
       rust_debug_loc (path.get_locus (), "failed to resolve the root");
@@ -176,7 +177,7 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
       // then this is just a normal path-in-expression
       NodeId root_resolved_node_id = UNKNOWN_NODEID;
       bool ok = resolver->lookup_resolved_type (
-	qual_path_type.get_type ()->get_mappings ().get_nodeid (),
+	qual_path_type.get_type ().get_mappings ().get_nodeid (),
 	&root_resolved_node_id);
       rust_assert (ok);
 
@@ -189,8 +190,8 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
     }
 
   // Resolve the trait now
-  std::unique_ptr<HIR::TypePath> &trait_path_ref = qual_path_type.get_trait ();
-  TraitReference *trait_ref = TraitResolver::Resolve (*trait_path_ref.get ());
+  auto &trait_path_ref = qual_path_type.get_trait ();
+  TraitReference *trait_ref = TraitResolver::Resolve (trait_path_ref);
   if (trait_ref->is_error ())
     return;
 
@@ -203,9 +204,8 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
     }
 
   // get the predicate for the bound
-  auto specified_bound
-    = get_predicate_from_bound (*qual_path_type.get_trait ().get (),
-				qual_path_type.get_type ().get ());
+  auto specified_bound = get_predicate_from_bound (qual_path_type.get_trait (),
+						   qual_path_type.get_type ());
   if (specified_bound.is_error ())
     return;
 
@@ -213,18 +213,17 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
   root->inherit_bounds ({specified_bound});
 
   // lookup the associated item from the specified bound
-  std::unique_ptr<HIR::TypePathSegment> &item_seg
-    = path.get_associated_segment ();
-  HIR::PathIdentSegment item_seg_identifier = item_seg->get_ident_segment ();
+  HIR::TypePathSegment &item_seg = path.get_associated_segment ();
+  HIR::PathIdentSegment item_seg_identifier = item_seg.get_ident_segment ();
   TyTy::TypeBoundPredicateItem item
     = specified_bound.lookup_associated_item (item_seg_identifier.as_string ());
   if (item.is_error ())
     {
       std::string item_seg_ident_name, rich_msg;
-      item_seg_ident_name = qual_path_type.get_trait ()->as_string ();
+      item_seg_ident_name = qual_path_type.get_trait ().as_string ();
       rich_msg = "not found in `" + item_seg_ident_name + "`";
 
-      rich_location richloc (line_table, item_seg->get_locus ());
+      rich_location richloc (line_table, item_seg.get_locus ());
       richloc.add_fixit_replace (rich_msg.c_str ());
 
       rust_error_at (richloc, ErrorCode::E0576,
@@ -296,17 +295,16 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
     }
 
   // turbo-fish segment path::<ty>
-  if (item_seg->get_type () == HIR::TypePathSegment::SegmentType::GENERIC)
+  if (item_seg.get_type () == HIR::TypePathSegment::SegmentType::GENERIC)
     {
-      HIR::TypePathSegmentGeneric &generic_seg
-	= static_cast<HIR::TypePathSegmentGeneric &> (*item_seg.get ());
+      auto &generic_seg = static_cast<HIR::TypePathSegmentGeneric &> (item_seg);
 
       // turbo-fish segment path::<ty>
       if (generic_seg.has_generic_args ())
 	{
 	  if (!translated->has_substitutions_defined ())
 	    {
-	      rust_error_at (item_seg->get_locus (),
+	      rust_error_at (item_seg.get_locus (),
 			     "substitutions not supported for %s",
 			     translated->as_string ().c_str ());
 	      translated
@@ -454,13 +452,13 @@ TypeCheckType::resolve_root_path (HIR::TypePath &path, size_t *offset,
       // turbo-fish segment path::<ty>
       if (seg->is_generic_segment ())
 	{
-	  HIR::TypePathSegmentGeneric *generic_segment
-	    = static_cast<HIR::TypePathSegmentGeneric *> (seg.get ());
+	  auto &generic_segment
+	    = static_cast<HIR::TypePathSegmentGeneric &> (*seg);
 
 	  auto regions = context->regions_from_generic_args (
-	    generic_segment->get_generic_args ());
+	    generic_segment.get_generic_args ());
 	  lookup = SubstMapper::Resolve (lookup, path.get_locus (),
-					 &generic_segment->get_generic_args (),
+					 &generic_segment.get_generic_args (),
 					 regions);
 	  if (lookup->get_kind () == TyTy::TypeKind::ERROR)
 	    return new TyTy::ErrorType (seg->get_mappings ().get_hirid ());
@@ -569,12 +567,12 @@ TypeCheckType::resolve_segments (
 
       if (seg->is_generic_segment ())
 	{
-	  auto *generic_segment
-	    = static_cast<HIR::TypePathSegmentGeneric *> (seg.get ());
+	  auto &generic_segment
+	    = static_cast<HIR::TypePathSegmentGeneric &> (*seg);
 
 	  std::vector<TyTy::Region> regions;
 	  for (auto &lifetime :
-	       generic_segment->get_generic_args ().get_lifetime_args ())
+	       generic_segment.get_generic_args ().get_lifetime_args ())
 	    {
 	      auto region = context->lookup_and_resolve_lifetime (lifetime);
 	      if (!region.has_value ())
@@ -587,7 +585,7 @@ TypeCheckType::resolve_segments (
 	    }
 
 	  tyseg = SubstMapper::Resolve (tyseg, expr_locus,
-					&generic_segment->get_generic_args (),
+					&generic_segment.get_generic_args (),
 					regions);
 	  if (tyseg->get_kind () == TyTy::TypeKind::ERROR)
 	    return new TyTy::ErrorType (expr_id);
@@ -651,7 +649,7 @@ TypeCheckType::visit (HIR::TraitObjectType &type)
 
       TyTy::TypeBoundPredicate predicate = get_predicate_from_bound (
 	trait_bound.get_path (),
-	nullptr /*this will setup a PLACEHOLDER for self*/);
+	tl::nullopt /*this will setup a PLACEHOLDER for self*/);
 
       if (!predicate.is_error ()
 	  && predicate.is_object_safe (true, type.get_locus ()))
@@ -667,33 +665,31 @@ TypeCheckType::visit (HIR::TraitObjectType &type)
 void
 TypeCheckType::visit (HIR::ArrayType &type)
 {
-  auto capacity_type = TypeCheckExpr::Resolve (type.get_size_expr ().get ());
+  auto capacity_type = TypeCheckExpr::Resolve (type.get_size_expr ());
   if (capacity_type->get_kind () == TyTy::TypeKind::ERROR)
     return;
 
   TyTy::BaseType *expected_ty = nullptr;
   bool ok = context->lookup_builtin ("usize", &expected_ty);
   rust_assert (ok);
-  context->insert_type (type.get_size_expr ()->get_mappings (), expected_ty);
+  context->insert_type (type.get_size_expr ().get_mappings (), expected_ty);
 
-  unify_site (type.get_size_expr ()->get_mappings ().get_hirid (),
+  unify_site (type.get_size_expr ().get_mappings ().get_hirid (),
 	      TyTy::TyWithLocation (expected_ty),
 	      TyTy::TyWithLocation (capacity_type,
-				    type.get_size_expr ()->get_locus ()),
-	      type.get_size_expr ()->get_locus ());
+				    type.get_size_expr ().get_locus ()),
+	      type.get_size_expr ().get_locus ());
 
-  TyTy::BaseType *base
-    = TypeCheckType::Resolve (type.get_element_type ().get ());
+  TyTy::BaseType *base = TypeCheckType::Resolve (type.get_element_type ());
   translated = new TyTy::ArrayType (type.get_mappings ().get_hirid (),
-				    type.get_locus (), *type.get_size_expr (),
+				    type.get_locus (), type.get_size_expr (),
 				    TyTy::TyVar (base->get_ref ()));
 }
 
 void
 TypeCheckType::visit (HIR::SliceType &type)
 {
-  TyTy::BaseType *base
-    = TypeCheckType::Resolve (type.get_element_type ().get ());
+  TyTy::BaseType *base = TypeCheckType::Resolve (type.get_element_type ());
   translated
     = new TyTy::SliceType (type.get_mappings ().get_hirid (), type.get_locus (),
 			   TyTy::TyVar (base->get_ref ()));
@@ -701,7 +697,7 @@ TypeCheckType::visit (HIR::SliceType &type)
 void
 TypeCheckType::visit (HIR::ReferenceType &type)
 {
-  TyTy::BaseType *base = TypeCheckType::Resolve (type.get_base_type ().get ());
+  TyTy::BaseType *base = TypeCheckType::Resolve (type.get_base_type ());
   rust_assert (type.has_lifetime ());
   auto region = context->lookup_and_resolve_lifetime (type.get_lifetime ());
   if (!region.has_value ())
@@ -718,7 +714,7 @@ TypeCheckType::visit (HIR::ReferenceType &type)
 void
 TypeCheckType::visit (HIR::RawPointerType &type)
 {
-  TyTy::BaseType *base = TypeCheckType::Resolve (type.get_base_type ().get ());
+  TyTy::BaseType *base = TypeCheckType::Resolve (type.get_base_type ());
   translated
     = new TyTy::PointerType (type.get_mappings ().get_hirid (),
 			     TyTy::TyVar (base->get_ref ()), type.get_mut ());
@@ -744,21 +740,21 @@ TypeCheckType::visit (HIR::NeverType &type)
 }
 
 TyTy::ParamType *
-TypeResolveGenericParam::Resolve (HIR::GenericParam *param, bool apply_sized)
+TypeResolveGenericParam::Resolve (HIR::GenericParam &param, bool apply_sized)
 {
   TypeResolveGenericParam resolver (apply_sized);
-  switch (param->get_kind ())
+  switch (param.get_kind ())
     {
     case HIR::GenericParam::GenericKind::TYPE:
-      resolver.visit (static_cast<HIR::TypeParam &> (*param));
+      resolver.visit (static_cast<HIR::TypeParam &> (param));
       break;
 
     case HIR::GenericParam::GenericKind::CONST:
-      resolver.visit (static_cast<HIR::ConstGenericParam &> (*param));
+      resolver.visit (static_cast<HIR::ConstGenericParam &> (param));
       break;
 
     case HIR::GenericParam::GenericKind::LIFETIME:
-      resolver.visit (static_cast<HIR::LifetimeParam &> (*param));
+      resolver.visit (static_cast<HIR::LifetimeParam &> (param));
       break;
     }
   return resolver.resolved;
@@ -780,9 +776,9 @@ void
 TypeResolveGenericParam::visit (HIR::TypeParam &param)
 {
   if (param.has_type ())
-    TypeCheckType::Resolve (param.get_type ().get ());
+    TypeCheckType::Resolve (param.get_type ());
 
-  HIR::Type *implicit_self_bound = nullptr;
+  std::unique_ptr<HIR::Type> implicit_self_bound = nullptr;
   if (param.has_type_param_bounds ())
     {
       // We need two possible parameter types. One with no Bounds and one with
@@ -800,8 +796,8 @@ TypeResolveGenericParam::visit (HIR::TypeParam &param)
 				      param.get_mappings ().get_nodeid (),
 				      implicit_id,
 				      param.get_mappings ().get_local_defid ());
-      implicit_self_bound
-	= new HIR::TypePath (mappings, {}, BUILTINS_LOCATION, false);
+      implicit_self_bound = Rust::make_unique<HIR::TypePath> (
+	HIR::TypePath (mappings, {}, BUILTINS_LOCATION, false));
     }
 
   std::map<DefId, std::vector<TyTy::TypeBoundPredicate>> predicates;
@@ -830,13 +826,11 @@ TypeResolveGenericParam::visit (HIR::TypeParam &param)
 	  switch (bound->get_bound_type ())
 	    {
 	      case HIR::TypeParamBound::BoundType::TRAITBOUND: {
-		HIR::TraitBound *b
-		  = static_cast<HIR::TraitBound *> (bound.get ());
+		HIR::TraitBound &b = static_cast<HIR::TraitBound &> (*bound);
 
-		TyTy::TypeBoundPredicate predicate
-		  = get_predicate_from_bound (b->get_path (),
-					      implicit_self_bound,
-					      b->get_polarity ());
+		TyTy::TypeBoundPredicate predicate = get_predicate_from_bound (
+		  b.get_path (), tl::optional (std::ref (*implicit_self_bound)),
+		  b.get_polarity ());
 		if (!predicate.is_error ())
 		  {
 		    switch (predicate.get_polarity ())
@@ -849,7 +843,7 @@ TypeResolveGenericParam::visit (HIR::TypeParam &param)
 			  else
 			    {
 			      // emit error message
-			      rich_location r (line_table, b->get_locus ());
+			      rich_location r (line_table, b.get_locus ());
 			      r.add_range (predicate.get ()->get_locus ());
 			      rust_error_at (
 				r, "antibound for %s is not applied here",
@@ -947,7 +941,7 @@ ResolveWhereClauseItem::visit (HIR::TypeBoundWhereClauseItem &item)
     }
 
   auto &binding_type_path = item.get_bound_type ();
-  TyTy::BaseType *binding = TypeCheckType::Resolve (binding_type_path.get ());
+  TyTy::BaseType *binding = TypeCheckType::Resolve (binding_type_path);
 
   // FIXME double check there might be a trait cycle here see TypeParam handling
 
@@ -960,8 +954,7 @@ ResolveWhereClauseItem::visit (HIR::TypeBoundWhereClauseItem &item)
 	    auto *b = static_cast<HIR::TraitBound *> (bound.get ());
 
 	    TyTy::TypeBoundPredicate predicate
-	      = get_predicate_from_bound (b->get_path (),
-					  binding_type_path.get ());
+	      = get_predicate_from_bound (b->get_path (), binding_type_path);
 	    if (!predicate.is_error ())
 	      specified_bounds.push_back (std::move (predicate));
 	  }
@@ -991,7 +984,7 @@ ResolveWhereClauseItem::visit (HIR::TypeBoundWhereClauseItem &item)
   // When we apply these bounds we must lookup which type this binding
   // resolves to, as this is the type which will be used during resolution
   // of the block.
-  NodeId ast_node_id = binding_type_path->get_mappings ().get_nodeid ();
+  NodeId ast_node_id = binding_type_path.get_mappings ().get_nodeid ();
 
   // then lookup the reference_node_id
   NodeId ref_node_id = UNKNOWN_NODEID;
@@ -1000,7 +993,7 @@ ResolveWhereClauseItem::visit (HIR::TypeBoundWhereClauseItem &item)
       // FIXME
       rust_error_at (UNDEF_LOCATION,
 		     "Failed to lookup type reference for node: %s",
-		     binding_type_path->as_string ().c_str ());
+		     binding_type_path.as_string ().c_str ());
       return;
     }
 
@@ -1013,7 +1006,7 @@ ResolveWhereClauseItem::visit (HIR::TypeBoundWhereClauseItem &item)
 	{
 	  rust_error_at (mappings.lookup_location (*hid),
 			 "Failed to resolve where-clause binding type: %s",
-			 binding_type_path->as_string ().c_str ());
+			 binding_type_path.as_string ().c_str ());
 	  return;
 	}
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h
index a440250388a3..ab29152ef45b 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.h
@@ -31,7 +31,7 @@ namespace Resolver {
 class TypeCheckResolveGenericArguments : public TypeCheckBase
 {
 public:
-  static HIR::GenericArgs resolve (HIR::TypePathSegment *segment);
+  static HIR::GenericArgs resolve (HIR::TypePathSegment &segment);
 
   void visit (HIR::TypePathSegmentGeneric &generic);
 
@@ -46,7 +46,7 @@ private:
 class TypeCheckType : public TypeCheckBase, public HIR::HIRTypeVisitor
 {
 public:
-  static TyTy::BaseType *Resolve (HIR::Type *type);
+  static TyTy::BaseType *Resolve (HIR::Type &type);
 
   void visit (HIR::BareFunctionType &fntype) override;
   void visit (HIR::TupleType &tuple) override;
@@ -96,7 +96,7 @@ private:
 class TypeResolveGenericParam : public TypeCheckBase
 {
 public:
-  static TyTy::ParamType *Resolve (HIR::GenericParam *param,
+  static TyTy::ParamType *Resolve (HIR::GenericParam &param,
 				   bool apply_sized = true);
 
 protected:
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
index 628660a208c9..8e69f286d5c7 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -19,10 +19,12 @@
 #include "rust-hir-type-check.h"
 #include "rust-hir-full.h"
 #include "rust-hir-inherent-impl-overlap.h"
+#include "rust-hir-pattern.h"
 #include "rust-hir-type-check-expr.h"
 #include "rust-hir-type-check-item.h"
 #include "rust-hir-type-check-pattern.h"
 #include "rust-hir-type-check-struct-field.h"
+#include "rust-make-unique.h"
 #include "rust-immutable-name-resolution-context.h"
 
 // for flag_name_resolution_2_0
@@ -140,11 +142,10 @@ TyTy::BaseType *
 TraitItemReference::get_type_from_constant (
   /*const*/ HIR::TraitItemConst &constant) const
 {
-  TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ().get ());
+  TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
   if (constant.has_expr ())
     {
-      TyTy::BaseType *expr
-	= TypeCheckExpr::Resolve (constant.get_expr ().get ());
+      TyTy::BaseType *expr = TypeCheckExpr::Resolve (constant.get_expr ());
 
       return unify_site (constant.get_mappings ().get_hirid (),
 			 TyTy::TyWithLocation (type),
@@ -185,7 +186,7 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
 
 	      case HIR::GenericParam::GenericKind::TYPE: {
 		auto param_type
-		  = TypeResolveGenericParam::Resolve (generic_param.get ());
+		  = TypeResolveGenericParam::Resolve (*generic_param);
 		context->insert_type (generic_param->get_mappings (),
 				      param_type);
 
@@ -209,8 +210,7 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
     ret_type = TyTy::TupleType::get_unit_type ();
   else
     {
-      auto resolved
-	= TypeCheckType::Resolve (function.get_return_type ().get ());
+      auto resolved = TypeCheckType::Resolve (function.get_return_type ());
       if (resolved->get_kind () == TyTy::TypeKind::ERROR)
 	{
 	  rust_error_at (fn.get_locus (), "failed to resolve return type");
@@ -219,10 +219,12 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
 
       ret_type = resolved->clone ();
       ret_type->set_ref (
-	function.get_return_type ()->get_mappings ().get_hirid ());
+	function.get_return_type ().get_mappings ().get_hirid ());
     }
 
   std::vector<std::pair<HIR::Pattern *, TyTy::BaseType *> > params;
+
+  std::unique_ptr<HIR::IdentifierPattern> self_pattern = nullptr;
   if (function.is_method ())
     {
       // these are implicit mappings and not used
@@ -236,16 +238,17 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
       // for compilation to know parameter names. The types are ignored
       // but we reuse the HIR identifier pattern which requires it
       HIR::SelfParam &self_param = function.get_self ();
-      HIR::IdentifierPattern *self_pattern = new HIR::IdentifierPattern (
-	mapping, {"self"}, self_param.get_locus (), self_param.is_ref (),
-	self_param.is_mut () ? Mutability::Mut : Mutability::Imm,
-	std::unique_ptr<HIR::Pattern> (nullptr));
+      self_pattern
+	= Rust::make_unique<HIR::IdentifierPattern> (HIR::IdentifierPattern (
+	  mapping, {"self"}, self_param.get_locus (), self_param.is_ref (),
+	  self_param.is_mut () ? Mutability::Mut : Mutability::Imm,
+	  std::unique_ptr<HIR::Pattern> (nullptr)));
       // might have a specified type
       TyTy::BaseType *self_type = nullptr;
       if (self_param.has_type ())
 	{
-	  std::unique_ptr<HIR::Type> &specified_type = self_param.get_type ();
-	  self_type = TypeCheckType::Resolve (specified_type.get ());
+	  HIR::Type &specified_type = self_param.get_type ();
+	  self_type = TypeCheckType::Resolve (specified_type);
 	}
       else
 	{
@@ -288,18 +291,20 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
 
       context->insert_type (self_param.get_mappings (), self_type);
       params.push_back (
-	std::pair<HIR::Pattern *, TyTy::BaseType *> (self_pattern, self_type));
+	std::pair<HIR::Pattern *, TyTy::BaseType *> (self_pattern.get (),
+						     self_type));
     }
 
   for (auto &param : function.get_function_params ())
     {
       // get the name as well required for later on
-      auto param_tyty = TypeCheckType::Resolve (param.get_type ().get ());
-      params.push_back (std::pair<HIR::Pattern *, TyTy::BaseType *> (
-	param.get_param_name ().get (), param_tyty));
+      auto param_tyty = TypeCheckType::Resolve (param.get_type ());
+      params.push_back (
+	std::pair<HIR::Pattern *, TyTy::BaseType *> (&param.get_param_name (),
+						     param_tyty));
 
       context->insert_type (param.get_mappings (), param_tyty);
-      TypeCheckPattern::Resolve (param.get_param_name ().get (), param_tyty);
+      TypeCheckPattern::Resolve (param.get_param_name (), param_tyty);
     }
 
   auto &mappings = Analysis::Mappings::get ();
@@ -327,7 +332,7 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
     function.get_function_name ().as_string (), ident,
     function.is_method () ? TyTy::FnType::FNTYPE_IS_METHOD_FLAG
 			  : TyTy::FnType::FNTYPE_DEFAULT_FLAGS,
-    ABI::RUST, std::move (params), ret_type, substitutions,
+    ABI::RUST, params, ret_type, substitutions,
     TyTy::SubstitutionArgumentMappings::empty (
       context->get_lifetime_resolver ().get_num_bound_regions ()),
     region_constraints);
diff --git a/gcc/rust/typecheck/rust-hir-type-check.h b/gcc/rust/typecheck/rust-hir-type-check.h
index 5b1fe220890b..e0918e9d93ca 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.h
+++ b/gcc/rust/typecheck/rust-hir-type-check.h
@@ -42,7 +42,7 @@ public:
   };
 
   TypeCheckContextItem (HIR::Function *item);
-  TypeCheckContextItem (HIR::ImplBlock *impl_block, HIR::Function *item);
+  TypeCheckContextItem (HIR::ImplBlock &impl_block, HIR::Function *item);
   TypeCheckContextItem (HIR::TraitItemFunc *trait_item);
   TypeCheckContextItem (const TypeCheckContextItem &other);
 
diff --git a/gcc/rust/typecheck/rust-type-util.cc b/gcc/rust/typecheck/rust-type-util.cc
index 0ed712473536..b7587526431f 100644
--- a/gcc/rust/typecheck/rust-type-util.cc
+++ b/gcc/rust/typecheck/rust-type-util.cc
@@ -99,8 +99,9 @@ query_type (HirId reference, TyTy::BaseType **result)
       auto block = mappings.lookup_hir_extern_block (extern_item->second);
       rust_assert (block.has_value ());
 
-      *result = TypeCheckTopLevelExternItem::Resolve (extern_item->first,
-						      *block.value ());
+      *result
+	= TypeCheckTopLevelExternItem::Resolve (*extern_item.value ().first,
+						*block.value ());
       context->query_completed (reference);
       return true;
     }
diff --git a/gcc/rust/typecheck/rust-typecheck-context.cc b/gcc/rust/typecheck/rust-typecheck-context.cc
index 0fb8224861ea..1cd5dabf8222 100644
--- a/gcc/rust/typecheck/rust-typecheck-context.cc
+++ b/gcc/rust/typecheck/rust-typecheck-context.cc
@@ -646,9 +646,9 @@ TypeCheckContextItem::TypeCheckContextItem (HIR::Function *item)
   : type (ItemType::ITEM), item (item)
 {}
 
-TypeCheckContextItem::TypeCheckContextItem (HIR::ImplBlock *impl_block,
+TypeCheckContextItem::TypeCheckContextItem (HIR::ImplBlock &impl_block,
 					    HIR::Function *item)
-  : type (ItemType::IMPL_ITEM), item (impl_block, item)
+  : type (ItemType::IMPL_ITEM), item (&impl_block, item)
 {}
 
 TypeCheckContextItem::TypeCheckContextItem (HIR::TraitItemFunc *trait_item)
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc b/gcc/rust/typecheck/rust-tyty-bounds.cc
index b73e59291297..32c55cd03f1c 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.cc
+++ b/gcc/rust/typecheck/rust-tyty-bounds.cc
@@ -70,7 +70,7 @@ TypeBoundsProbe::scan ()
       if (!impl->has_trait_ref ())
 	return true;
 
-      HirId impl_ty_id = impl->get_type ()->get_mappings ().get_hirid ();
+      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;
@@ -81,7 +81,7 @@ TypeBoundsProbe::scan ()
 	    return true;
 	}
 
-      possible_trait_paths.push_back ({impl->get_trait_ref ().get (), impl});
+      possible_trait_paths.push_back ({&impl->get_trait_ref (), impl});
       return true;
     });
 
@@ -182,9 +182,10 @@ TypeCheckBase::resolve_trait_path (HIR::TypePath &path)
 }
 
 TyTy::TypeBoundPredicate
-TypeCheckBase::get_predicate_from_bound (HIR::TypePath &type_path,
-					 HIR::Type *associated_self,
-					 BoundPolarity polarity)
+TypeCheckBase::get_predicate_from_bound (
+  HIR::TypePath &type_path,
+  tl::optional<std::reference_wrapper<HIR::Type>> associated_self,
+  BoundPolarity polarity)
 {
   TyTy::TypeBoundPredicate lookup = TyTy::TypeBoundPredicate::error ();
   bool already_resolved
@@ -215,9 +216,9 @@ TypeCheckBase::get_predicate_from_bound (HIR::TypePath &type_path,
       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 ();
+	auto &final_function_seg
+	  = static_cast<HIR::TypePathSegmentFunction &> (*final_seg);
+	auto &fn = final_function_seg.get_function_path ();
 
 	// we need to make implicit generic args which must be an implicit
 	// Tuple
@@ -243,7 +244,7 @@ TypeCheckBase::get_predicate_from_bound (HIR::TypePath &type_path,
 	// resolve the fn_once_output type which assumes there must be an output
 	// set
 	rust_assert (fn.has_return_type ());
-	TypeCheckType::Resolve (fn.get_return_type ().get ());
+	TypeCheckType::Resolve (fn.get_return_type ());
 
 	HIR::TraitItem *trait_item
 	  = mappings
@@ -252,10 +253,10 @@ TypeCheckBase::get_predicate_from_bound (HIR::TypePath &type_path,
 	      .value ();
 
 	std::vector<HIR::GenericArgsBinding> bindings;
-	location_t output_locus = fn.get_return_type ()->get_locus ();
+	location_t output_locus = fn.get_return_type ().get_locus ();
 	HIR::GenericArgsBinding binding (Identifier (
 					   trait_item->trait_identifier ()),
-					 fn.get_return_type ()->clone_type (),
+					 fn.get_return_type ().clone_type (),
 					 output_locus);
 	bindings.push_back (std::move (binding));
 
@@ -271,11 +272,11 @@ TypeCheckBase::get_predicate_from_bound (HIR::TypePath &type_path,
       break;
     }
 
-  if (associated_self != nullptr)
+  if (associated_self.has_value ())
     {
       std::vector<std::unique_ptr<HIR::Type>> type_args;
-      type_args.push_back (
-	std::unique_ptr<HIR::Type> (associated_self->clone_type ()));
+      type_args.push_back (std::unique_ptr<HIR::Type> (
+	associated_self.value ().get ().clone_type ()));
       for (auto &arg : args.get_type_args ())
 	{
 	  type_args.push_back (std::unique_ptr<HIR::Type> (arg->clone_type ()));
@@ -292,7 +293,7 @@ TypeCheckBase::get_predicate_from_bound (HIR::TypePath &type_path,
   if (!args.is_empty () || predicate.requires_generic_args ())
     {
       // this is applying generic arguments to a trait reference
-      predicate.apply_generic_arguments (&args, associated_self != nullptr);
+      predicate.apply_generic_arguments (&args, associated_self.has_value ());
     }
 
   context->insert_resolved_predicate (type_path.get_mappings ().get_hirid (),
diff --git a/gcc/rust/typecheck/rust-tyty-call.cc b/gcc/rust/typecheck/rust-tyty-call.cc
index ad3b2c3e75b7..23a4a059691c 100644
--- a/gcc/rust/typecheck/rust-tyty-call.cc
+++ b/gcc/rust/typecheck/rust-tyty-call.cc
@@ -80,7 +80,7 @@ TypeCheckCallExpr::visit (ADTType &type)
       BaseType *field_tyty = field->get_field_type ();
       location_t arg_locus = argument->get_locus ();
 
-      BaseType *arg = Resolver::TypeCheckExpr::Resolve (argument.get ());
+      BaseType *arg = Resolver::TypeCheckExpr::Resolve (*argument);
       if (arg->get_kind () == TyTy::TypeKind::ERROR)
 	{
 	  rust_error_at (argument->get_locus (),
@@ -139,8 +139,7 @@ TypeCheckCallExpr::visit (FnType &type)
   for (auto &argument : call.get_arguments ())
     {
       location_t arg_locus = argument->get_locus ();
-      auto argument_expr_tyty
-	= Resolver::TypeCheckExpr::Resolve (argument.get ());
+      auto argument_expr_tyty = Resolver::TypeCheckExpr::Resolve (*argument);
       if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR)
 	{
 	  rust_error_at (
@@ -152,8 +151,8 @@ TypeCheckCallExpr::visit (FnType &type)
       // it might be a variadic function
       if (i < type.num_params ())
 	{
-	  auto fnparam = type.param_at (i);
-	  HIR::Pattern *fn_param_pattern = fnparam.first;
+	  auto &fnparam = type.param_at (i);
+	  auto &fn_param_pattern = fnparam.first;
 	  BaseType *param_ty = fnparam.second;
 	  location_t param_locus
 	    = fn_param_pattern == nullptr
@@ -272,8 +271,7 @@ TypeCheckCallExpr::visit (FnPtr &type)
     {
       location_t arg_locus = argument->get_locus ();
       BaseType *fnparam = type.get_param_type_at (i);
-      auto argument_expr_tyty
-	= Resolver::TypeCheckExpr::Resolve (argument.get ());
+      auto argument_expr_tyty = Resolver::TypeCheckExpr::Resolve (*argument);
       if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR)
 	{
 	  rust_error_at (
@@ -322,8 +320,7 @@ TypeCheckMethodCallExpr::go (FnType *ref, HIR::MethodCallExpr &call,
   std::vector<Argument> args;
   for (auto &arg : call.get_arguments ())
     {
-      BaseType *argument_expr_tyty
-	= Resolver::TypeCheckExpr::Resolve (arg.get ());
+      BaseType *argument_expr_tyty = Resolver::TypeCheckExpr::Resolve (*arg);
       if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR)
 	{
 	  rust_error_at (arg->get_locus (),
@@ -337,7 +334,7 @@ TypeCheckMethodCallExpr::go (FnType *ref, HIR::MethodCallExpr &call,
 
   TypeCheckMethodCallExpr checker (call.get_mappings (), args,
 				   call.get_locus (),
-				   call.get_receiver ()->get_locus (),
+				   call.get_receiver ().get_locus (),
 				   adjusted_self, context);
   return checker.check (*ref);
 }
@@ -377,7 +374,7 @@ TypeCheckMethodCallExpr::check (FnType &type)
     {
       location_t arg_locus = argument.get_locus ();
 
-      auto fnparam = type.param_at (i);
+      auto &fnparam = type.param_at (i);
       HIR::Pattern *fn_param_pattern = fnparam.first;
       BaseType *param_ty = fnparam.second;
       location_t param_locus
diff --git a/gcc/rust/typecheck/rust-tyty-subst.cc b/gcc/rust/typecheck/rust-tyty-subst.cc
index 575f04a3030c..a12ad91192d3 100644
--- a/gcc/rust/typecheck/rust-tyty-subst.cc
+++ b/gcc/rust/typecheck/rust-tyty-subst.cc
@@ -630,7 +630,7 @@ SubstitutionRef::get_mappings_from_generic_args (
 	  for (auto &binding : args.get_binding_args ())
 	    {
 	      BaseType *resolved
-		= Resolver::TypeCheckType::Resolve (binding.get_type ().get ());
+		= Resolver::TypeCheckType::Resolve (binding.get_type ());
 	      if (resolved == nullptr
 		  || resolved->get_kind () == TyTy::TypeKind::ERROR)
 		{
@@ -696,7 +696,7 @@ SubstitutionRef::get_mappings_from_generic_args (
   std::vector<SubstitutionArg> mappings = used_arguments.get_mappings ();
   for (auto &arg : args.get_type_args ())
     {
-      BaseType *resolved = Resolver::TypeCheckType::Resolve (arg.get ());
+      BaseType *resolved = Resolver::TypeCheckType::Resolve (*arg);
       if (resolved == nullptr || resolved->get_kind () == TyTy::TypeKind::ERROR)
 	{
 	  return SubstitutionArgumentMappings::error ();
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 068e39021183..639a39bcbf93 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -31,6 +31,7 @@
 #include "rust-hir-type-bounds.h"
 
 #include "options.h"
+#include <functional>
 
 namespace Rust {
 namespace TyTy {
@@ -595,7 +596,8 @@ BaseType::monomorphized_clone () const
     {
       std::vector<std::pair<HIR::Pattern *, BaseType *>> cloned_params;
       for (auto &p : fn->get_params ())
-	cloned_params.push_back ({p.first, p.second->monomorphized_clone ()});
+	cloned_params.push_back (std::pair<HIR::Pattern *, BaseType *> (
+	  p.first, p.second->monomorphized_clone ()));
 
       BaseType *retty = fn->get_return_type ()->monomorphized_clone ();
       return new FnType (fn->get_ref (), fn->get_ty_ref (), fn->get_id (),
@@ -1341,9 +1343,10 @@ VariantDef::variant_type_string (VariantType type)
 }
 
 VariantDef::VariantDef (HirId id, DefId defid, std::string identifier,
-			RustIdent ident, HIR::Expr *discriminant)
+			RustIdent ident,
+			std::unique_ptr<HIR::Expr> &&discriminant)
   : id (id), defid (defid), identifier (identifier), ident (ident),
-    discriminant (discriminant)
+    discriminant (std::move (discriminant))
 
 {
   type = VariantType::NUM;
@@ -1352,34 +1355,15 @@ VariantDef::VariantDef (HirId id, DefId defid, std::string identifier,
 
 VariantDef::VariantDef (HirId id, DefId defid, std::string identifier,
 			RustIdent ident, VariantType type,
-			HIR::Expr *discriminant,
+			std::unique_ptr<HIR::Expr> &&discriminant,
 			std::vector<StructFieldType *> fields)
   : id (id), defid (defid), identifier (identifier), ident (ident), type (type),
-    discriminant (discriminant), fields (fields)
+    discriminant (std::move (discriminant)), fields (fields)
 {
   rust_assert ((type == VariantType::NUM && fields.empty ())
 	       || (type == VariantType::TUPLE || type == VariantType::STRUCT));
 }
 
-VariantDef::VariantDef (const VariantDef &other)
-  : id (other.id), defid (other.defid), identifier (other.identifier),
-    ident (other.ident), type (other.type), discriminant (other.discriminant),
-    fields (other.fields)
-{}
-
-VariantDef &
-VariantDef::operator= (const VariantDef &other)
-{
-  id = other.id;
-  identifier = other.identifier;
-  type = other.type;
-  discriminant = other.discriminant;
-  fields = other.fields;
-  ident = other.ident;
-
-  return *this;
-}
-
 VariantDef &
 VariantDef::get_error_node ()
 {
@@ -1475,11 +1459,11 @@ VariantDef::lookup_field (const std::string &lookup,
   return false;
 }
 
-HIR::Expr *
-VariantDef::get_discriminant () const
+HIR::Expr &
+VariantDef::get_discriminant ()
 {
   rust_assert (discriminant != nullptr);
-  return discriminant;
+  return *discriminant;
 }
 
 std::string
@@ -1533,8 +1517,8 @@ VariantDef::clone () const
   for (auto &f : fields)
     cloned_fields.push_back ((StructFieldType *) f->clone ());
 
-  return new VariantDef (id, defid, identifier, ident, type, discriminant,
-			 cloned_fields);
+  return new VariantDef (id, defid, identifier, ident, type,
+			 discriminant->clone_expr (), cloned_fields);
 }
 
 VariantDef *
@@ -1544,8 +1528,8 @@ VariantDef::monomorphized_clone () const
   for (auto &f : fields)
     cloned_fields.push_back ((StructFieldType *) f->monomorphized_clone ());
 
-  return new VariantDef (id, defid, identifier, ident, type, discriminant,
-			 cloned_fields);
+  return new VariantDef (id, defid, identifier, ident, type,
+			 discriminant->clone_expr (), cloned_fields);
 }
 
 const RustIdent &
@@ -1895,7 +1879,7 @@ FnType::as_string () const
   std::string params_str = "";
   for (auto &param : params)
     {
-      auto pattern = param.first;
+      auto &pattern = param.first;
       auto ty = param.second;
       params_str += pattern->as_string () + " " + ty->as_string ();
       params_str += ",";
@@ -1965,7 +1949,8 @@ FnType::clone () const
 {
   std::vector<std::pair<HIR::Pattern *, BaseType *>> cloned_params;
   for (auto &p : params)
-    cloned_params.push_back ({p.first, p.second->clone ()});
+    cloned_params.push_back (
+      std::pair<HIR::Pattern *, BaseType *> (p.first, p.second->clone ()));
 
   return new FnType (get_ref (), get_ty_ref (), get_id (), get_identifier (),
 		     ident, flags, abi, std::move (cloned_params),
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index d73db3d265ad..f394b8d91971 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -28,6 +28,9 @@
 #include "rust-tyty-subst.h"
 #include "rust-tyty-region.h"
 #include "rust-system.h"
+#include "rust-hir.h"
+
+#include <limits>
 
 namespace Rust {
 
@@ -567,16 +570,12 @@ public:
   static std::string variant_type_string (VariantType type);
 
   VariantDef (HirId id, DefId defid, std::string identifier, RustIdent ident,
-	      HIR::Expr *discriminant);
+	      std::unique_ptr<HIR::Expr> &&discriminant);
 
   VariantDef (HirId id, DefId defid, std::string identifier, RustIdent ident,
-	      VariantType type, HIR::Expr *discriminant,
+	      VariantType type, std::unique_ptr<HIR::Expr> &&discriminant,
 	      std::vector<StructFieldType *> fields);
 
-  VariantDef (const VariantDef &other);
-
-  VariantDef &operator= (const VariantDef &other);
-
   static VariantDef &get_error_node ();
   bool is_error () const;
 
@@ -597,7 +596,7 @@ public:
   bool lookup_field (const std::string &lookup, StructFieldType **field_lookup,
 		     size_t *index) const;
 
-  HIR::Expr *get_discriminant () const;
+  HIR::Expr &get_discriminant ();
 
   std::string as_string () const;
 
@@ -616,7 +615,7 @@ private:
   RustIdent ident;
   VariantType type;
   // can either be a structure or a discriminant value
-  HIR::Expr *discriminant;
+  std::unique_ptr<HIR::Expr> discriminant;
   std::vector<StructFieldType *> fields;
 };
 
@@ -787,8 +786,8 @@ public:
     : CallableTypeInterface (ref, ref, TypeKind::FNDEF, ident, refs),
       SubstitutionRef (std::move (subst_refs), substitution_argument_mappings,
 		       region_constraints),
-      params (std::move (params)), type (type), flags (flags),
-      identifier (identifier), id (id), abi (abi)
+      params (params), type (type), flags (flags), identifier (identifier),
+      id (id), abi (abi)
   {
     LocalDefId local_def_id = id.localDefId;
     rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID);
@@ -804,8 +803,8 @@ public:
     : CallableTypeInterface (ref, ty_ref, TypeKind::FNDEF, ident, refs),
       SubstitutionRef (std::move (subst_refs), substitution_argument_mappings,
 		       region_constraints),
-      params (params), type (type), flags (flags), identifier (identifier),
-      id (id), abi (abi)
+      params (std::move (params)), type (type), flags (flags),
+      identifier (identifier), id (id), abi (abi)
   {
     LocalDefId local_def_id = id.localDefId;
     rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID);
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index 03b3343eaa17..d1504e108c16 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -459,7 +459,7 @@ Mappings::insert_hir_impl_block (HIR::ImplBlock *item)
   auto id = item->get_mappings ().get_hirid ();
   rust_assert (!lookup_hir_impl_block (id));
 
-  HirId impl_type_id = item->get_type ()->get_mappings ().get_hirid ();
+  HirId impl_type_id = item->get_type ().get_mappings ().get_hirid ();
   hirImplBlockMappings[id] = item;
   hirImplBlockTypeMappings[impl_type_id] = item;
   insert_node_to_hir (item->get_mappings ().get_nodeid (), id);


More information about the Gcc-cvs mailing list