https://gcc.gnu.org/g:6b5039f20e8827549e7946a280a80bb5db0b10ce

commit 6b5039f20e8827549e7946a280a80bb5db0b10ce
Author: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com>
Date:   Fri Mar 8 14:42:10 2024 +0100

    Refactor HIR with optionals, references & newtypes
    
    The HIR made heavy use of pair and other unamed types which can be
    difficult to read.
    
    gcc/rust/ChangeLog:
    
            * backend/rust-compile-base.cc: Use FnParam getter.
            * backend/rust-compile-expr.cc (CompileExpr::visit): Likewise.
            * backend/rust-compile-intrinsic.cc: Likewise.
            * backend/rust-compile-type.cc: Likewise.
            * checks/errors/privacy/rust-privacy-reporter.cc 
(PrivacyReporter::visit):
            Only visit childrens if not missing.
            * checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit): Use
            a reference instead of a raw pointer.
            * hir/tree/rust-hir-expr.h: Add presence function for return
            expression.
            * hir/tree/rust-hir-item.h: Remove take_param_name.
            * hir/tree/rust-hir.h: Make mapping getter const.
            * typecheck/rust-hir-dot-operator.cc (MethodResolver::Select): Use
            getter.
            * typecheck/rust-hir-type-check-expr.cc: Likewise.
            * typecheck/rust-hir-type-check-implitem.cc: Use FnParam vector 
instead
            of std::pair of Pattern and BaseType.
            * typecheck/rust-hir-type-check-item.cc: Likewise.
            * typecheck/rust-hir-type-check.cc: Likewise.
            * typecheck/rust-tyty-call.cc (TypeCheckCallExpr::visit): Use 
getters.
            (TypeCheckMethodCallExpr::check): Likewise.
            * typecheck/rust-tyty-cmp.h: Likewise.
            * typecheck/rust-tyty.cc: Use FnParam.
            * typecheck/rust-tyty.h (class FnParam): Add FnParam to handle 
function
            parameters instead of handling std::pairs.
            * typecheck/rust-unify.cc (UnifyRules::expect_fndef): Use getters.
            (UnifyRules::expect_fnptr): Likewise.
    
    Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com>

Diff:
---
 gcc/rust/backend/rust-compile-base.cc              |  2 +-
 gcc/rust/backend/rust-compile-expr.cc              |  4 +-
 gcc/rust/backend/rust-compile-intrinsic.cc         | 17 +++---
 gcc/rust/backend/rust-compile-type.cc              |  4 +-
 .../checks/errors/privacy/rust-privacy-reporter.cc | 11 ++--
 gcc/rust/checks/errors/rust-unsafe-checker.cc      |  2 +-
 gcc/rust/hir/tree/rust-hir-expr.h                  |  2 +
 gcc/rust/hir/tree/rust-hir-item.h                  |  2 -
 gcc/rust/hir/tree/rust-hir.h                       |  5 +-
 gcc/rust/typecheck/rust-hir-dot-operator.cc        |  2 +-
 gcc/rust/typecheck/rust-hir-type-check-expr.cc     |  4 +-
 gcc/rust/typecheck/rust-hir-type-check-implitem.cc | 28 ++++-----
 gcc/rust/typecheck/rust-hir-type-check-item.cc     |  6 +-
 gcc/rust/typecheck/rust-hir-type-check.cc          | 18 +++---
 gcc/rust/typecheck/rust-tyty-call.cc               | 16 ++---
 gcc/rust/typecheck/rust-tyty-cmp.h                 |  6 +-
 gcc/rust/typecheck/rust-tyty.cc                    | 30 +++++-----
 gcc/rust/typecheck/rust-tyty.h                     | 69 ++++++++++++++--------
 gcc/rust/typecheck/rust-unify.cc                   |  6 +-
 19 files changed, 122 insertions(+), 112 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-base.cc 
b/gcc/rust/backend/rust-compile-base.cc
index 966ff527c15a..d272374cadc3 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -711,7 +711,7 @@ HIRCompileBase::compile_function (
   for (auto &referenced_param : function_params)
     {
       auto &tyty_param = fntype->param_at (i++);
-      auto param_tyty = tyty_param.second;
+      auto param_tyty = tyty_param.get_type ();
       auto compiled_param_type = TyTyResolveCompile::compile (ctx, param_tyty);
 
       location_t param_locus = referenced_param.get_locus ();
diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index 7d41f635716e..35a6f7044090 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -1267,7 +1267,7 @@ CompileExpr::visit (HIR::CallExpr &expr)
 
     const TyTy::FnType *fn = static_cast<const TyTy::FnType *> (base);
     auto &param = fn->param_at (index);
-    *result = param.second;
+    *result = param.get_type ();
 
     return true;
   };
@@ -1401,7 +1401,7 @@ CompileExpr::visit (HIR::MethodCallExpr &expr)
       // assignments are coercion sites so lets convert the rvalue if
       // necessary, offset from the already adjusted implicit self
       bool ok;
-      TyTy::BaseType *expected = fntype->param_at (i + 1).second;
+      TyTy::BaseType *expected = fntype->param_at (i + 1).get_type ();
 
       TyTy::BaseType *actual = nullptr;
       ok = ctx->get_tyctx ()->lookup_type (
diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc 
b/gcc/rust/backend/rust-compile-intrinsic.cc
index 0ffc3634e130..08b64439dab6 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -315,13 +315,13 @@ compile_fn_params (Context *ctx, TyTy::FnType *fntype, 
tree fndecl,
 {
   for (auto &parm : fntype->get_params ())
     {
-      auto &referenced_param = parm.first;
-      auto &param_tyty = parm.second;
+      auto &referenced_param = parm.get_pattern ();
+      auto param_tyty = parm.get_type ();
       auto compiled_param_type = TyTyResolveCompile::compile (ctx, param_tyty);
 
-      location_t param_locus = referenced_param->get_locus ();
+      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);
@@ -496,9 +496,10 @@ transmute_handler (Context *ctx, TyTy::FnType *fntype)
       rust_error_at (fntype->get_locus (),
                     "cannot transmute between types of different sizes, or "
                     "dependently-sized types");
-      rust_inform (fntype->get_ident ().locus, "source type: %qs (%lu bits)",
-                  fntype->get_params ().at (0).second->as_string ().c_str (),
-                  (unsigned long) source_size);
+      rust_inform (
+       fntype->get_ident ().locus, "source type: %qs (%lu bits)",
+       fntype->get_params ().at (0).get_type ()->as_string ().c_str (),
+       (unsigned long) source_size);
       rust_inform (fntype->get_ident ().locus, "target type: %qs (%lu bits)",
                   fntype->get_return_type ()->as_string ().c_str (),
                   (unsigned long) target_size);
@@ -1226,7 +1227,7 @@ assume_handler (Context *ctx, TyTy::FnType *fntype)
   // TODO: make sure this is actually helping the compiler optimize
 
   rust_assert (fntype->get_params ().size () == 1);
-  rust_assert (fntype->param_at (0).second->get_kind ()
+  rust_assert (fntype->param_at (0).get_type ()->get_kind ()
               == TyTy::TypeKind::BOOL);
 
   tree lookup = NULL_TREE;
diff --git a/gcc/rust/backend/rust-compile-type.cc 
b/gcc/rust/backend/rust-compile-type.cc
index e01335247143..c6d249e341dd 100644
--- a/gcc/rust/backend/rust-compile-type.cc
+++ b/gcc/rust/backend/rust-compile-type.cc
@@ -208,12 +208,12 @@ TyTyResolveCompile::visit (const TyTy::FnType &type)
 
   for (auto &param_pair : type.get_params ())
     {
-      auto param_tyty = param_pair.second;
+      auto param_tyty = param_pair.get_type ();
       auto compiled_param_type
        = TyTyResolveCompile::compile (ctx, param_tyty, trait_object_mode);
 
       auto compiled_param = Backend::typed_identifier (
-       param_pair.first->as_string (), compiled_param_type,
+       param_pair.get_pattern ().as_string (), compiled_param_type,
        ctx->get_mappings ().lookup_location (param_tyty->get_ref ()));
 
       parameters.push_back (compiled_param);
diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc 
b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
index a5e2f85418f7..39212bf97f51 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
@@ -497,8 +497,8 @@ PrivacyReporter::visit (HIR::BlockExpr &expr)
   for (auto &stmt : expr.get_statements ())
     stmt->accept_vis (*this);
 
-  auto &last_expr = expr.get_final_expr ();
-  last_expr.accept_vis (*this);
+  if (expr.has_final_expr ())
+    expr.get_final_expr ().accept_vis (*this);
 }
 
 void
@@ -508,8 +508,8 @@ PrivacyReporter::visit (HIR::ContinueExpr &)
 void
 PrivacyReporter::visit (HIR::BreakExpr &expr)
 {
-  auto &break_expr = expr.get_expr ();
-  break_expr.accept_vis (*this);
+  if (expr.has_break_expr ())
+    expr.get_expr ().accept_vis (*this);
 }
 
 void
@@ -551,7 +551,8 @@ PrivacyReporter::visit (HIR::RangeToInclExpr &)
 void
 PrivacyReporter::visit (HIR::ReturnExpr &expr)
 {
-  expr.get_expr ().accept_vis (*this);
+  if (expr.has_expr ())
+    expr.get_expr ().accept_vis (*this);
 }
 
 void
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc 
b/gcc/rust/checks/errors/rust-unsafe-checker.cc
index 10181b7574f7..d1ebd15197bd 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.cc
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc
@@ -482,7 +482,7 @@ UnsafeChecker::visit (MethodCallExpr &expr)
   context.lookup_type (expr.get_method_name ().get_mappings ().get_hirid (),
                       &method_type);
 
-  auto fn = *static_cast<TyTy::FnType *> (method_type);
+  auto &fn = static_cast<TyTy::FnType &> (*method_type);
 
   auto method = mappings.lookup_hir_implitem (fn.get_ref ());
   if (!unsafe_context.is_in_context () && method)
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h 
b/gcc/rust/hir/tree/rust-hir-expr.h
index c4a821e98643..c0d10c2b97f1 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -2238,6 +2238,7 @@ public:
 
   bool is_final_stmt (Stmt *stmt) { return statements.back ().get () == stmt; }
 
+  bool has_final_expr () { return expr != nullptr; }
   Expr &get_final_expr () { return *expr; }
 
   std::vector<std::unique_ptr<Stmt> > &get_statements () { return statements; }
@@ -2785,6 +2786,7 @@ public:
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRExpressionVisitor &vis) override;
 
+  bool has_expr () { return return_expr != nullptr; }
   Expr &get_expr () { return *return_expr; }
 
   ExprType get_expression_type () const override final
diff --git a/gcc/rust/hir/tree/rust-hir-item.h 
b/gcc/rust/hir/tree/rust-hir-item.h
index ba554d545c2a..92e8fc3712e1 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -549,8 +549,6 @@ public:
 
   Pattern &get_param_name () { return *param_name; }
 
-  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; }
diff --git a/gcc/rust/hir/tree/rust-hir.h b/gcc/rust/hir/tree/rust-hir.h
index 44dcc8e768e2..05d855c0a7db 100644
--- a/gcc/rust/hir/tree/rust-hir.h
+++ b/gcc/rust/hir/tree/rust-hir.h
@@ -465,7 +465,10 @@ public:
 
   virtual void accept_vis (HIRTypeVisitor &vis) = 0;
 
-  virtual Analysis::NodeMapping get_mappings () const { return mappings; }
+  virtual const Analysis::NodeMapping &get_mappings () const
+  {
+    return mappings;
+  }
   virtual location_t get_locus () const { return locus; }
 
 protected:
diff --git a/gcc/rust/typecheck/rust-hir-dot-operator.cc 
b/gcc/rust/typecheck/rust-hir-dot-operator.cc
index 38535ccfd743..31034eed2fbf 100644
--- a/gcc/rust/typecheck/rust-hir-dot-operator.cc
+++ b/gcc/rust/typecheck/rust-hir-dot-operator.cc
@@ -62,7 +62,7 @@ MethodResolver::Select (std::set<MethodCandidate> &candidates,
       for (size_t i = 0; i < arguments.size (); i++)
        {
          TyTy::BaseType *arg = arguments.at (i);
-         TyTy::BaseType *param = fn.get_params ().at (i + 1).second;
+         TyTy::BaseType *param = fn.get_params ().at (i + 1).get_type ();
          TyTy::BaseType *coerced
            = try_coercion (0, TyTy::TyWithLocation (param),
                            TyTy::TyWithLocation (arg), UNDEF_LOCATION);
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index f9dace10c8c7..8bb5058d3fc1 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -1795,7 +1795,7 @@ TypeCheckExpr::resolve_operator_overload (LangItem::Kind 
lang_item_type,
 
   // typecheck the self
   unify_site (expr.get_mappings ().get_hirid (),
-             TyTy::TyWithLocation (fnparam.second),
+             TyTy::TyWithLocation (fnparam.get_type ()),
              TyTy::TyWithLocation (adjusted_self), expr.get_locus ());
   if (rhs == nullptr)
     {
@@ -1806,7 +1806,7 @@ TypeCheckExpr::resolve_operator_overload (LangItem::Kind 
lang_item_type,
       rust_assert (type->num_params () == 2);
       auto &fnparam = type->param_at (1);
       unify_site (expr.get_mappings ().get_hirid (),
-                 TyTy::TyWithLocation (fnparam.second),
+                 TyTy::TyWithLocation (fnparam.get_type ()),
                  TyTy::TyWithLocation (rhs), expr.get_locus ());
     }
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc 
b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
index 79afbd528da2..6a748f4666b2 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
@@ -130,8 +130,7 @@ TypeCheckTopLevelExternItem::visit 
(HIR::ExternalFunctionItem &function)
        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;
+  std::vector<TyTy::FnParam> params;
   for (auto &param : function.get_function_params ())
     {
       // get the name as well required for later on
@@ -143,14 +142,12 @@ TypeCheckTopLevelExternItem::visit 
(HIR::ExternalFunctionItem &function)
                                     mappings.get_next_hir_id (crate_num),
                                     UNKNOWN_LOCAL_DEFID);
 
-      param_pattern = Rust::make_unique<HIR::IdentifierPattern> (
+      auto 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.get (),
-                                                    param_tyty));
+      params.push_back (TyTy::FnParam (std::move (param_pattern), param_tyty));
 
       context->insert_type (param.get_mappings (), param_tyty);
 
@@ -375,8 +372,7 @@ TypeCheckImplItem::visit (HIR::Function &function)
        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;
+  std::vector<TyTy::FnParam> params;
   if (function.is_method ())
     {
       // these are implicit mappings and not used
@@ -390,10 +386,11 @@ 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`?
-      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)));
+      std::unique_ptr<HIR::Pattern> 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;
@@ -450,9 +447,7 @@ 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.get (),
-                                                    self_type));
+      params.push_back (TyTy::FnParam (std::move (self_pattern), self_type));
     }
 
   for (auto &param : function.get_function_params ())
@@ -464,8 +459,7 @@ TypeCheckImplItem::visit (HIR::Function &function)
       TypeCheckPattern::Resolve (param.get_param_name (), param_tyty);
 
       params.push_back (
-       std::pair<HIR::Pattern *, TyTy::BaseType *> (&param.get_param_name (),
-                                                    param_tyty));
+       TyTy::FnParam (param.get_param_name ().clone_pattern (), param_tyty));
     }
 
   tl::optional<CanonicalPath> canonical_path;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc 
b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index 2a5922c10d7f..12784d2650c5 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -574,15 +574,15 @@ TypeCheckItem::visit (HIR::Function &function)
        function.get_return_type ().get_mappings ().get_hirid ());
     }
 
-  std::vector<std::pair<HIR::Pattern *, TyTy::BaseType *>> params;
+  std::vector<TyTy::FnParam> 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 ());
-      params.emplace_back (&param.get_param_name (), param_tyty);
-
       context->insert_type (param.get_mappings (), param_tyty);
       TypeCheckPattern::Resolve (param.get_param_name (), param_tyty);
+      params.push_back (
+       TyTy::FnParam (param.get_param_name ().clone_pattern (), param_tyty));
     }
 
   auto path = CanonicalPath::create_empty ();
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc 
b/gcc/rust/typecheck/rust-hir-type-check.cc
index 48e9c0579515..a30408c0b7f7 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -222,9 +222,8 @@ TraitItemReference::get_type_from_fn (/*const*/ 
HIR::TraitItemFunc &fn) const
        function.get_return_type ().get_mappings ().get_hirid ());
     }
 
-  std::vector<std::pair<HIR::Pattern *, TyTy::BaseType *> > params;
+  std::vector<TyTy::FnParam> params;
 
-  std::unique_ptr<HIR::IdentifierPattern> self_pattern = nullptr;
   if (function.is_method ())
     {
       // these are implicit mappings and not used
@@ -238,7 +237,7 @@ 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 ();
-      self_pattern
+      std::unique_ptr<HIR::Pattern> 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,
@@ -290,21 +289,18 @@ 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.get (),
-                                                    self_type));
+      params.push_back (TyTy::FnParam (std::move (self_pattern), 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 ());
-      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 (), param_tyty);
+      // FIXME: Should we take the name ? Use a shared pointer instead ?
+      params.push_back (
+       TyTy::FnParam (param.get_param_name ().clone_pattern (), param_tyty));
     }
 
   auto &mappings = Analysis::Mappings::get ();
@@ -332,7 +328,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, params, ret_type, substitutions,
+    ABI::RUST, std::move (params), ret_type, substitutions,
     TyTy::SubstitutionArgumentMappings::empty (
       context->get_lifetime_resolver ().get_num_bound_regions ()),
     region_constraints);
diff --git a/gcc/rust/typecheck/rust-tyty-call.cc 
b/gcc/rust/typecheck/rust-tyty-call.cc
index 36a6b3d858d8..da1c383b2ca2 100644
--- a/gcc/rust/typecheck/rust-tyty-call.cc
+++ b/gcc/rust/typecheck/rust-tyty-call.cc
@@ -152,12 +152,12 @@ TypeCheckCallExpr::visit (FnType &type)
       if (i < type.num_params ())
        {
          auto &fnparam = type.param_at (i);
-         auto &fn_param_pattern = fnparam.first;
-         BaseType *param_ty = fnparam.second;
+         auto &fn_param_pattern = fnparam.get_pattern ();
+         BaseType *param_ty = fnparam.get_type ();
          location_t param_locus
-           = fn_param_pattern == nullptr
+           = fnparam.has_pattern ()
                ? mappings.lookup_location (param_ty->get_ref ())
-               : fn_param_pattern->get_locus ();
+               : fn_param_pattern.get_locus ();
 
          HirId coercion_side_id = argument->get_mappings ().get_hirid ();
          auto resolved_argument_type
@@ -375,12 +375,12 @@ TypeCheckMethodCallExpr::check (FnType &type)
       location_t arg_locus = argument.get_locus ();
 
       auto &fnparam = type.param_at (i);
-      HIR::Pattern *fn_param_pattern = fnparam.first;
-      BaseType *param_ty = fnparam.second;
+      HIR::Pattern &fn_param_pattern = fnparam.get_pattern ();
+      BaseType *param_ty = fnparam.get_type ();
       location_t param_locus
-       = fn_param_pattern == nullptr
+       = fnparam.has_pattern ()
            ? mappings.lookup_location (param_ty->get_ref ())
-           : fn_param_pattern->get_locus ();
+           : fn_param_pattern.get_locus ();
 
       auto argument_expr_tyty = argument.get_argument_type ();
       HirId coercion_side_id = argument.get_mappings ().get_hirid ();
diff --git a/gcc/rust/typecheck/rust-tyty-cmp.h 
b/gcc/rust/typecheck/rust-tyty-cmp.h
index d4552153dea8..95cbb6f6418d 100644
--- a/gcc/rust/typecheck/rust-tyty-cmp.h
+++ b/gcc/rust/typecheck/rust-tyty-cmp.h
@@ -735,8 +735,8 @@ public:
 
     for (size_t i = 0; i < base->num_params (); i++)
       {
-       auto a = base->param_at (i).second;
-       auto b = type.param_at (i).second;
+       auto a = base->param_at (i).get_type ();
+       auto b = type.param_at (i).get_type ();
 
        if (!a->can_eq (b, emit_error_flag))
          {
@@ -831,7 +831,7 @@ public:
     for (size_t i = 0; i < base->num_params (); i++)
       {
        auto this_param = base->get_param_type_at (i);
-       auto other_param = type.param_at (i).second;
+       auto other_param = type.param_at (i).get_type ();
        if (!this_param->can_eq (other_param, emit_error_flag))
          {
            BaseCmp::visit (type);
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 19196f72c479..ec910b2e6740 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -594,10 +594,9 @@ BaseType::monomorphized_clone () const
     }
   else if (auto fn = x->try_as<const FnType> ())
     {
-      std::vector<std::pair<HIR::Pattern *, BaseType *>> cloned_params;
+      std::vector<TyTy::FnParam> cloned_params;
       for (auto &p : fn->get_params ())
-       cloned_params.push_back (std::pair<HIR::Pattern *, BaseType *> (
-         p.first, p.second->monomorphized_clone ()));
+       cloned_params.push_back (p.clone ());
 
       BaseType *retty = fn->get_return_type ()->monomorphized_clone ();
       return new FnType (fn->get_ref (), fn->get_ty_ref (), fn->get_id (),
@@ -688,7 +687,7 @@ BaseType::is_concrete () const
     {
       for (const auto &param : fn->get_params ())
        {
-         if (!param.second->is_concrete ())
+         if (!param.get_type ()->is_concrete ())
            return false;
        }
       return fn->get_return_type ()->is_concrete ();
@@ -1879,9 +1878,9 @@ FnType::as_string () const
   std::string params_str = "";
   for (auto &param : params)
     {
-      auto &pattern = param.first;
-      auto ty = param.second;
-      params_str += pattern->as_string () + " " + ty->as_string ();
+      auto &pattern = param.get_pattern ();
+      auto ty = param.get_type ();
+      params_str += pattern.as_string () + " " + ty->as_string ();
       params_str += ",";
     }
 
@@ -1902,7 +1901,7 @@ FnType::is_equal (const BaseType &other) const
   if (get_kind () != other.get_kind ())
     return false;
 
-  auto other2 = static_cast<const FnType &> (other);
+  auto &other2 = static_cast<const FnType &> (other);
   if (get_identifier ().compare (other2.get_identifier ()) != 0)
     return false;
 
@@ -1936,8 +1935,8 @@ FnType::is_equal (const BaseType &other) const
 
   for (size_t i = 0; i < num_params (); i++)
     {
-      auto lhs = param_at (i).second;
-      auto rhs = other2.param_at (i).second;
+      auto lhs = param_at (i).get_type ();
+      auto rhs = other2.param_at (i).get_type ();
       if (!lhs->is_equal (*rhs))
        return false;
     }
@@ -1947,10 +1946,9 @@ FnType::is_equal (const BaseType &other) const
 BaseType *
 FnType::clone () const
 {
-  std::vector<std::pair<HIR::Pattern *, BaseType *>> cloned_params;
+  std::vector<TyTy::FnParam> cloned_params;
   for (auto &p : params)
-    cloned_params.push_back (
-      std::pair<HIR::Pattern *, BaseType *> (p.first, p.second->clone ()));
+    cloned_params.push_back (p.clone ());
 
   return new FnType (get_ref (), get_ty_ref (), get_id (), get_identifier (),
                     ident, flags, abi, std::move (cloned_params),
@@ -2024,7 +2022,7 @@ FnType::handle_substitions (SubstitutionArgumentMappings 
&subst_mappings)
 
   for (auto &param : fn->get_params ())
     {
-      auto fty = param.second;
+      auto fty = param.get_type ();
 
       bool is_param_ty = fty->get_kind () == TypeKind::PARAM;
       if (is_param_ty)
@@ -2043,7 +2041,7 @@ FnType::handle_substitions (SubstitutionArgumentMappings 
&subst_mappings)
                {
                  auto new_field = argt->clone ();
                  new_field->set_ref (fty->get_ref ());
-                 param.second = new_field;
+                 param.set_type (new_field);
                }
              else
                {
@@ -2067,7 +2065,7 @@ FnType::handle_substitions (SubstitutionArgumentMappings 
&subst_mappings)
 
          auto new_field = concrete->clone ();
          new_field->set_ref (fty->get_ref ());
-         param.second = new_field;
+         param.set_type (new_field);
        }
     }
 
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index c20a172f2b35..2a8786169821 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -766,6 +766,34 @@ private:
   ReprOptions repr;
 };
 
+class FnParam
+{
+public:
+  FnParam (std::unique_ptr<HIR::Pattern> pattern, BaseType *type)
+    : pattern (std::move (pattern)), type (type)
+  {}
+
+  FnParam (const FnParam &) = delete;
+  FnParam (FnParam &&) = default;
+  FnParam &operator= (FnParam &&) = default;
+
+  HIR::Pattern &get_pattern () { return *pattern; }
+  const HIR::Pattern &get_pattern () const { return *pattern; }
+
+  bool has_pattern () { return pattern != nullptr; }
+  BaseType *get_type () const { return type; }
+  void set_type (BaseType *new_type) { type = new_type; }
+
+  FnParam clone () const
+  {
+    return FnParam (pattern->clone_pattern (), type->monomorphized_clone ());
+  }
+
+private:
+  std::unique_ptr<HIR::Pattern> pattern;
+  BaseType *type;
+};
+
 class FnType : public CallableTypeInterface, public SubstitutionRef
 {
 public:
@@ -777,25 +805,23 @@ public:
   static const uint8_t FNTYPE_IS_VARADIC_FLAG = 0X04;
 
   FnType (HirId ref, DefId id, std::string identifier, RustIdent ident,
-         uint8_t flags, ABI abi,
-         std::vector<std::pair<HIR::Pattern *, BaseType *>> params,
-         BaseType *type, std::vector<SubstitutionParamMapping> subst_refs,
+         uint8_t flags, ABI abi, std::vector<FnParam> params, BaseType *type,
+         std::vector<SubstitutionParamMapping> subst_refs,
          SubstitutionArgumentMappings substitution_argument_mappings,
          RegionConstraints region_constraints,
          std::set<HirId> refs = std::set<HirId> ())
     : CallableTypeInterface (ref, 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);
   }
 
   FnType (HirId ref, HirId ty_ref, DefId id, std::string identifier,
-         RustIdent ident, uint8_t flags, ABI abi,
-         std::vector<std::pair<HIR::Pattern *, BaseType *>> params,
+         RustIdent ident, uint8_t flags, ABI abi, std::vector<FnParam> params,
          BaseType *type, std::vector<SubstitutionParamMapping> subst_refs,
          SubstitutionArgumentMappings substitution_argument_mappings,
          RegionConstraints region_constraints,
@@ -810,6 +836,9 @@ public:
     rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID);
   }
 
+  FnType (const FnType &) = delete;
+  FnType (FnType &&) = default;
+
   void accept_vis (TyVisitor &vis) override;
   void accept_vis (TyConstVisitor &vis) const override;
 
@@ -843,28 +872,16 @@ public:
   BaseType *get_self_type () const
   {
     rust_assert (is_method ());
-    return param_at (0).second;
+    return param_at (0).get_type ();
   }
 
-  std::vector<std::pair<HIR::Pattern *, BaseType *>> &get_params ()
-  {
-    return params;
-  }
+  std::vector<FnParam> &get_params () { return params; }
 
-  const std::vector<std::pair<HIR::Pattern *, BaseType *>> &get_params () const
-  {
-    return params;
-  }
+  const std::vector<FnParam> &get_params () const { return params; }
 
-  std::pair<HIR::Pattern *, BaseType *> &param_at (size_t idx)
-  {
-    return params.at (idx);
-  }
+  FnParam &param_at (size_t idx) { return params.at (idx); }
 
-  const std::pair<HIR::Pattern *, BaseType *> &param_at (size_t idx) const
-  {
-    return params.at (idx);
-  }
+  const FnParam &param_at (size_t idx) const { return params.at (idx); }
 
   BaseType *clone () const final override;
 
@@ -881,7 +898,7 @@ public:
 
   WARN_UNUSED_RESULT BaseType *get_param_type_at (size_t index) const override
   {
-    return param_at (index).second;
+    return param_at (index).get_type ();
   }
 
   WARN_UNUSED_RESULT BaseType *get_return_type () const override
@@ -890,7 +907,7 @@ public:
   }
 
 private:
-  std::vector<std::pair<HIR::Pattern *, BaseType *>> params;
+  std::vector<FnParam> params;
   BaseType *type;
   uint8_t flags;
   std::string identifier;
diff --git a/gcc/rust/typecheck/rust-unify.cc b/gcc/rust/typecheck/rust-unify.cc
index 8163d55b3c3a..d5344036fcc1 100644
--- a/gcc/rust/typecheck/rust-unify.cc
+++ b/gcc/rust/typecheck/rust-unify.cc
@@ -929,8 +929,8 @@ UnifyRules::expect_fndef (TyTy::FnType *ltype, 
TyTy::BaseType *rtype)
 
        for (size_t i = 0; i < ltype->num_params (); i++)
          {
-           auto a = ltype->param_at (i).second;
-           auto b = type.param_at (i).second;
+           auto a = ltype->param_at (i).get_type ();
+           auto b = type.param_at (i).get_type ();
 
            auto unified_param
              = UnifyRules::Resolve (TyTy::TyWithLocation (a),
@@ -1069,7 +1069,7 @@ UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, 
TyTy::BaseType *rtype)
        for (size_t i = 0; i < ltype->num_params (); i++)
          {
            auto this_param = ltype->get_param_type_at (i);
-           auto other_param = type.param_at (i).second;
+           auto other_param = type.param_at (i).get_type ();
 
            auto unified_param
              = UnifyRules::Resolve (TyTy::TyWithLocation (this_param),

Reply via email to