public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: arthur.cohen@embecosm.com
To: gcc-patches@gcc.gnu.org
Cc: gcc-rust@gcc.gnu.org, Philip Herron <herron.philip@googlemail.com>
Subject: [committed 38/88] gccrs: Refactor SubstitutionRef base class into its own CC file
Date: Wed,  5 Apr 2023 16:03:22 +0200	[thread overview]
Message-ID: <20230405140411.3016563-39-arthur.cohen@embecosm.com> (raw)
In-Reply-To: <20230405140411.3016563-1-arthur.cohen@embecosm.com>

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

Signed-off-by: Philip Herron <herron.philip@googlemail.com>

gcc/rust/ChangeLog:

	* Make-lang.in: update the makefile
	* typecheck/rust-tyty.cc (SubstitutionParamMapping::need_substitution): likewise
	(SubstitutionParamMapping::override_context): likewise
	(SubstitutionRef::get_mappings_from_generic_args): likewise
	(SubstitutionRef::infer_substitions): likewise
	(SubstitutionRef::are_mappings_bound): likewise
	(SubstitutionRef::solve_missing_mappings_from_this): likewise
	(SubstitutionRef::monomorphize): likewise
	* typecheck/rust-tyty.h (class SubstitutionParamMapping): likewise
	(class SubstitutionArg): likewise
	(std::function<void): likewise
	(class SubstitutionArgumentMappings): likewise
	(class SubstitutionRef): likewise
	* typecheck/rust-tyty-subst.cc: New file.
	* typecheck/rust-tyty-subst.h: New file.
---
 gcc/rust/Make-lang.in                 |   1 +
 gcc/rust/typecheck/rust-tyty-subst.cc | 927 ++++++++++++++++++++++++++
 gcc/rust/typecheck/rust-tyty-subst.h  | 316 +++++++++
 gcc/rust/typecheck/rust-tyty.cc       | 466 -------------
 gcc/rust/typecheck/rust-tyty.h        | 464 +------------
 5 files changed, 1245 insertions(+), 929 deletions(-)
 create mode 100644 gcc/rust/typecheck/rust-tyty-subst.cc
 create mode 100644 gcc/rust/typecheck/rust-tyty-subst.h

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 2aa61bcfb19..5e173f1d2dc 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -117,6 +117,7 @@ GRS_OBJS = \
     rust/rust-tyty.o \
     rust/rust-tyty-util.o \
     rust/rust-tyty-call.o \
+    rust/rust-tyty-subst.o \
     rust/rust-tyctx.o \
     rust/rust-tyty-bounds.o \
     rust/rust-hir-type-check-util.o \
diff --git a/gcc/rust/typecheck/rust-tyty-subst.cc b/gcc/rust/typecheck/rust-tyty-subst.cc
new file mode 100644
index 00000000000..64001459b4d
--- /dev/null
+++ b/gcc/rust/typecheck/rust-tyty-subst.cc
@@ -0,0 +1,927 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-tyty-subst.h"
+#include "rust-hir-full.h"
+#include "rust-tyty.h"
+#include "rust-hir-type-check.h"
+#include "rust-substitution-mapper.h"
+#include "rust-hir-type-check-type.h"
+
+namespace Rust {
+namespace TyTy {
+
+SubstitutionParamMapping::SubstitutionParamMapping (
+  const HIR::TypeParam &generic, ParamType *param)
+  : generic (generic), param (param)
+{}
+
+SubstitutionParamMapping::SubstitutionParamMapping (
+  const SubstitutionParamMapping &other)
+  : generic (other.generic), param (other.param)
+{}
+
+std::string
+SubstitutionParamMapping::as_string () const
+{
+  if (param == nullptr)
+    return "nullptr";
+
+  return param->get_name ();
+}
+
+SubstitutionParamMapping
+SubstitutionParamMapping::clone () const
+{
+  return SubstitutionParamMapping (generic,
+				   static_cast<ParamType *> (param->clone ()));
+}
+
+ParamType *
+SubstitutionParamMapping::get_param_ty ()
+{
+  return param;
+}
+
+const ParamType *
+SubstitutionParamMapping::get_param_ty () const
+{
+  return param;
+}
+
+const HIR::TypeParam &
+SubstitutionParamMapping::get_generic_param ()
+{
+  return generic;
+};
+
+bool
+SubstitutionParamMapping::needs_substitution () const
+{
+  return !(get_param_ty ()->is_concrete ());
+}
+
+Location
+SubstitutionParamMapping::get_param_locus () const
+{
+  return generic.get_locus ();
+}
+
+bool
+SubstitutionParamMapping::param_has_default_ty () const
+{
+  return generic.has_type ();
+}
+
+BaseType *
+SubstitutionParamMapping::get_default_ty () const
+{
+  TyVar var (generic.get_type_mappings ().get_hirid ());
+  return var.get_tyty ();
+}
+
+bool
+SubstitutionParamMapping::need_substitution () const
+{
+  if (!param->can_resolve ())
+    return true;
+
+  auto resolved = param->resolve ();
+  return !resolved->is_concrete ();
+}
+
+bool
+SubstitutionParamMapping::fill_param_ty (
+  SubstitutionArgumentMappings &subst_mappings, Location locus)
+{
+  SubstitutionArg arg = SubstitutionArg::error ();
+  bool ok = subst_mappings.get_argument_for_symbol (get_param_ty (), &arg);
+  if (!ok)
+    return true;
+
+  TyTy::BaseType &type = *arg.get_tyty ();
+  if (type.get_kind () == TyTy::TypeKind::INFER)
+    {
+      type.inherit_bounds (*param);
+    }
+  else
+    {
+      if (!param->bounds_compatible (type, locus, true))
+	return false;
+    }
+
+  if (type.get_kind () == TypeKind::PARAM)
+    {
+      // delete param;
+      param = static_cast<ParamType *> (type.clone ());
+    }
+  else
+    {
+      // check the substitution is compatible with bounds
+      if (!param->bounds_compatible (type, locus, true))
+	return false;
+
+      // recursively pass this down to all HRTB's
+      for (auto &bound : param->get_specified_bounds ())
+	bound.handle_substitions (subst_mappings);
+
+      param->set_ty_ref (type.get_ref ());
+    }
+
+  return true;
+}
+
+void
+SubstitutionParamMapping::override_context ()
+{
+  if (!param->can_resolve ())
+    return;
+
+  auto mappings = Analysis::Mappings::get ();
+  auto context = Resolver::TypeCheckContext::get ();
+
+  context->insert_type (Analysis::NodeMapping (mappings->get_current_crate (),
+					       UNKNOWN_NODEID,
+					       param->get_ref (),
+					       UNKNOWN_LOCAL_DEFID),
+			param->resolve ());
+}
+
+SubstitutionArg::SubstitutionArg (const SubstitutionParamMapping *param,
+				  BaseType *argument)
+  : param (param), argument (argument)
+{}
+
+SubstitutionArg::SubstitutionArg (const SubstitutionArg &other)
+  : param (other.param), argument (other.argument)
+{}
+
+SubstitutionArg &
+SubstitutionArg::operator= (const SubstitutionArg &other)
+{
+  param = other.param;
+  argument = other.argument;
+  return *this;
+}
+
+BaseType *
+SubstitutionArg::get_tyty ()
+{
+  return argument;
+}
+
+const BaseType *
+SubstitutionArg::get_tyty () const
+{
+  return argument;
+}
+
+const SubstitutionParamMapping *
+SubstitutionArg::get_param_mapping () const
+{
+  return param;
+}
+
+SubstitutionArg
+SubstitutionArg::error ()
+{
+  return SubstitutionArg (nullptr, nullptr);
+}
+
+bool
+SubstitutionArg::is_error () const
+{
+  return param == nullptr || argument == nullptr;
+}
+
+bool
+SubstitutionArg::is_conrete () const
+{
+  if (argument != nullptr)
+    return true;
+
+  if (argument->get_kind () == TyTy::TypeKind::PARAM)
+    return false;
+
+  return argument->is_concrete ();
+}
+
+std::string
+SubstitutionArg::as_string () const
+{
+  return param->as_string ()
+	 + (argument != nullptr ? ":" + argument->as_string () : "");
+}
+
+// SubstitutionArgumentMappings
+
+SubstitutionArgumentMappings::SubstitutionArgumentMappings (
+  std::vector<SubstitutionArg> mappings,
+  std::map<std::string, BaseType *> binding_args, Location locus,
+  ParamSubstCb param_subst_cb, bool trait_item_flag)
+  : mappings (mappings), binding_args (binding_args), locus (locus),
+    param_subst_cb (param_subst_cb), trait_item_flag (trait_item_flag)
+{}
+
+SubstitutionArgumentMappings::SubstitutionArgumentMappings (
+  const SubstitutionArgumentMappings &other)
+  : mappings (other.mappings), binding_args (other.binding_args),
+    locus (other.locus), param_subst_cb (other.param_subst_cb),
+    trait_item_flag (other.trait_item_flag)
+{}
+
+SubstitutionArgumentMappings &
+SubstitutionArgumentMappings::operator= (
+  const SubstitutionArgumentMappings &other)
+{
+  mappings = other.mappings;
+  binding_args = other.binding_args;
+  locus = other.locus;
+  param_subst_cb = other.param_subst_cb;
+  trait_item_flag = other.trait_item_flag;
+
+  return *this;
+}
+
+SubstitutionArgumentMappings
+SubstitutionArgumentMappings::error ()
+{
+  return SubstitutionArgumentMappings ({}, {}, Location (), nullptr, false);
+}
+
+bool
+SubstitutionArgumentMappings::is_error () const
+{
+  return mappings.size () == 0;
+}
+
+bool
+SubstitutionArgumentMappings::get_argument_for_symbol (
+  const ParamType *param_to_find, SubstitutionArg *argument)
+{
+  for (auto &mapping : mappings)
+    {
+      const SubstitutionParamMapping *param = mapping.get_param_mapping ();
+      const ParamType *p = param->get_param_ty ();
+
+      if (p->get_symbol ().compare (param_to_find->get_symbol ()) == 0)
+	{
+	  *argument = mapping;
+	  return true;
+	}
+    }
+  return false;
+}
+
+bool
+SubstitutionArgumentMappings::get_argument_at (size_t index,
+					       SubstitutionArg *argument)
+{
+  if (index > mappings.size ())
+    return false;
+
+  *argument = mappings.at (index);
+  return true;
+}
+
+bool
+SubstitutionArgumentMappings::is_concrete () const
+{
+  for (auto &mapping : mappings)
+    {
+      if (!mapping.is_conrete ())
+	return false;
+    }
+  return true;
+}
+
+Location
+SubstitutionArgumentMappings::get_locus () const
+{
+  return locus;
+}
+
+size_t
+SubstitutionArgumentMappings::size () const
+{
+  return mappings.size ();
+}
+
+bool
+SubstitutionArgumentMappings::is_empty () const
+{
+  return size () == 0;
+}
+
+std::vector<SubstitutionArg> &
+SubstitutionArgumentMappings::get_mappings ()
+{
+  return mappings;
+}
+
+const std::vector<SubstitutionArg> &
+SubstitutionArgumentMappings::get_mappings () const
+{
+  return mappings;
+}
+
+std::map<std::string, BaseType *> &
+SubstitutionArgumentMappings::get_binding_args ()
+{
+  return binding_args;
+}
+
+const std::map<std::string, BaseType *> &
+SubstitutionArgumentMappings::get_binding_args () const
+{
+  return binding_args;
+}
+
+std::string
+SubstitutionArgumentMappings::as_string () const
+{
+  std::string buffer;
+  for (auto &mapping : mappings)
+    {
+      buffer += mapping.as_string () + ", ";
+    }
+  return "<" + buffer + ">";
+}
+
+void
+SubstitutionArgumentMappings::on_param_subst (const ParamType &p,
+					      const SubstitutionArg &a) const
+{
+  if (param_subst_cb == nullptr)
+    return;
+
+  param_subst_cb (p, a);
+}
+
+ParamSubstCb
+SubstitutionArgumentMappings::get_subst_cb () const
+{
+  return param_subst_cb;
+}
+
+bool
+SubstitutionArgumentMappings::trait_item_mode () const
+{
+  return trait_item_flag;
+}
+
+// SubstitutionRef
+
+SubstitutionRef::SubstitutionRef (
+  std::vector<SubstitutionParamMapping> substitutions,
+  SubstitutionArgumentMappings arguments)
+  : substitutions (substitutions), used_arguments (arguments)
+{}
+
+bool
+SubstitutionRef::has_substitutions () const
+{
+  return substitutions.size () > 0;
+}
+
+std::string
+SubstitutionRef::subst_as_string () const
+{
+  std::string buffer;
+  for (size_t i = 0; i < substitutions.size (); i++)
+    {
+      const SubstitutionParamMapping &sub = substitutions.at (i);
+      buffer += sub.as_string ();
+
+      if ((i + 1) < substitutions.size ())
+	buffer += ", ";
+    }
+
+  return buffer.empty () ? "" : "<" + buffer + ">";
+}
+
+bool
+SubstitutionRef::supports_associated_bindings () const
+{
+  return get_num_associated_bindings () > 0;
+}
+
+size_t
+SubstitutionRef::get_num_associated_bindings () const
+{
+  return 0;
+}
+
+TypeBoundPredicateItem
+SubstitutionRef::lookup_associated_type (const std::string &search)
+{
+  return TypeBoundPredicateItem::error ();
+}
+
+size_t
+SubstitutionRef::get_num_substitutions () const
+{
+  return substitutions.size ();
+}
+
+std::vector<SubstitutionParamMapping> &
+SubstitutionRef::get_substs ()
+{
+  return substitutions;
+}
+
+const std::vector<SubstitutionParamMapping> &
+SubstitutionRef::get_substs () const
+{
+  return substitutions;
+}
+
+std::vector<SubstitutionParamMapping>
+SubstitutionRef::clone_substs () const
+{
+  std::vector<SubstitutionParamMapping> clone;
+
+  for (auto &sub : substitutions)
+    clone.push_back (sub.clone ());
+
+  return clone;
+}
+
+void
+SubstitutionRef::override_context ()
+{
+  for (auto &sub : substitutions)
+    {
+      sub.override_context ();
+    }
+}
+
+bool
+SubstitutionRef::needs_substitution () const
+{
+  for (auto &sub : substitutions)
+    {
+      if (sub.need_substitution ())
+	return true;
+    }
+  return false;
+}
+
+bool
+SubstitutionRef::was_substituted () const
+{
+  return !needs_substitution ();
+}
+
+SubstitutionArgumentMappings
+SubstitutionRef::get_substitution_arguments () const
+{
+  return used_arguments;
+}
+
+size_t
+SubstitutionRef::num_required_substitutions () const
+{
+  size_t n = 0;
+  for (auto &p : substitutions)
+    {
+      if (p.needs_substitution ())
+	n++;
+    }
+  return n;
+}
+
+size_t
+SubstitutionRef::min_required_substitutions () const
+{
+  size_t n = 0;
+  for (auto &p : substitutions)
+    {
+      if (p.needs_substitution () && !p.param_has_default_ty ())
+	n++;
+    }
+  return n;
+}
+
+SubstitutionArgumentMappings
+SubstitutionRef::get_used_arguments () const
+{
+  return used_arguments;
+}
+
+SubstitutionArgumentMappings
+SubstitutionRef::get_mappings_from_generic_args (HIR::GenericArgs &args)
+{
+  std::map<std::string, BaseType *> binding_arguments;
+  if (args.get_binding_args ().size () > 0)
+    {
+      if (supports_associated_bindings ())
+	{
+	  if (args.get_binding_args ().size () > get_num_associated_bindings ())
+	    {
+	      RichLocation r (args.get_locus ());
+
+	      rust_error_at (r,
+			     "generic item takes at most %lu type binding "
+			     "arguments but %lu were supplied",
+			     (unsigned long) get_num_associated_bindings (),
+			     (unsigned long) args.get_binding_args ().size ());
+	      return SubstitutionArgumentMappings::error ();
+	    }
+
+	  for (auto &binding : args.get_binding_args ())
+	    {
+	      BaseType *resolved
+		= Resolver::TypeCheckType::Resolve (binding.get_type ().get ());
+	      if (resolved == nullptr
+		  || resolved->get_kind () == TyTy::TypeKind::ERROR)
+		{
+		  rust_error_at (binding.get_locus (),
+				 "failed to resolve type arguments");
+		  return SubstitutionArgumentMappings::error ();
+		}
+
+	      // resolve to relevant binding
+	      auto binding_item
+		= lookup_associated_type (binding.get_identifier ());
+	      if (binding_item.is_error ())
+		{
+		  rust_error_at (binding.get_locus (),
+				 "unknown associated type binding: %s",
+				 binding.get_identifier ().c_str ());
+		  return SubstitutionArgumentMappings::error ();
+		}
+
+	      binding_arguments[binding.get_identifier ()] = resolved;
+	    }
+	}
+      else
+	{
+	  RichLocation r (args.get_locus ());
+	  for (auto &binding : args.get_binding_args ())
+	    r.add_range (binding.get_locus ());
+
+	  rust_error_at (r, "associated type bindings are not allowed here");
+	  return SubstitutionArgumentMappings::error ();
+	}
+    }
+
+  // for inherited arguments
+  size_t offs = used_arguments.size ();
+  if (args.get_type_args ().size () + offs > substitutions.size ())
+    {
+      RichLocation r (args.get_locus ());
+      r.add_range (substitutions.front ().get_param_locus ());
+
+      rust_error_at (
+	r,
+	"generic item takes at most %lu type arguments but %lu were supplied",
+	(unsigned long) substitutions.size (),
+	(unsigned long) args.get_type_args ().size ());
+      return SubstitutionArgumentMappings::error ();
+    }
+
+  if (args.get_type_args ().size () + offs < min_required_substitutions ())
+    {
+      RichLocation r (args.get_locus ());
+      r.add_range (substitutions.front ().get_param_locus ());
+
+      rust_error_at (
+	r,
+	"generic item takes at least %lu type arguments but %lu were supplied",
+	(unsigned long) (min_required_substitutions () - offs),
+	(unsigned long) args.get_type_args ().size ());
+      return SubstitutionArgumentMappings::error ();
+    }
+
+  std::vector<SubstitutionArg> mappings = used_arguments.get_mappings ();
+  for (auto &arg : args.get_type_args ())
+    {
+      BaseType *resolved = Resolver::TypeCheckType::Resolve (arg.get ());
+      if (resolved == nullptr || resolved->get_kind () == TyTy::TypeKind::ERROR)
+	{
+	  rust_error_at (args.get_locus (), "failed to resolve type arguments");
+	  return SubstitutionArgumentMappings::error ();
+	}
+
+      SubstitutionArg subst_arg (&substitutions.at (offs), resolved);
+      offs++;
+      mappings.push_back (std::move (subst_arg));
+    }
+
+  // we must need to fill out defaults
+  size_t left_over
+    = num_required_substitutions () - min_required_substitutions ();
+  if (left_over > 0)
+    {
+      for (size_t offs = mappings.size (); offs < substitutions.size (); offs++)
+	{
+	  SubstitutionParamMapping &param = substitutions.at (offs);
+	  rust_assert (param.param_has_default_ty ());
+
+	  BaseType *resolved = param.get_default_ty ();
+	  if (resolved->get_kind () == TypeKind::ERROR)
+	    return SubstitutionArgumentMappings::error ();
+
+	  // this resolved default might already contain default parameters
+	  if (resolved->contains_type_parameters ())
+	    {
+	      SubstitutionArgumentMappings intermediate (mappings,
+							 binding_arguments,
+							 args.get_locus ());
+	      resolved = Resolver::SubstMapperInternal::Resolve (resolved,
+								 intermediate);
+
+	      if (resolved->get_kind () == TypeKind::ERROR)
+		return SubstitutionArgumentMappings::error ();
+	    }
+
+	  SubstitutionArg subst_arg (&param, resolved);
+	  mappings.push_back (std::move (subst_arg));
+	}
+    }
+
+  return SubstitutionArgumentMappings (mappings, binding_arguments,
+				       args.get_locus ());
+}
+
+BaseType *
+SubstitutionRef::infer_substitions (Location locus)
+{
+  std::vector<SubstitutionArg> args;
+  std::map<std::string, BaseType *> argument_mappings;
+  for (auto &p : get_substs ())
+    {
+      if (p.needs_substitution ())
+	{
+	  const std::string &symbol = p.get_param_ty ()->get_symbol ();
+	  auto it = argument_mappings.find (symbol);
+	  bool have_mapping = it != argument_mappings.end ();
+
+	  if (have_mapping)
+	    {
+	      args.push_back (SubstitutionArg (&p, it->second));
+	    }
+	  else
+	    {
+	      TyVar infer_var = TyVar::get_implicit_infer_var (locus);
+	      args.push_back (SubstitutionArg (&p, infer_var.get_tyty ()));
+	      argument_mappings[symbol] = infer_var.get_tyty ();
+	    }
+	}
+      else
+	{
+	  args.push_back (SubstitutionArg (&p, p.get_param_ty ()->resolve ()));
+	}
+    }
+
+  // FIXME do we need to add inference variables to all the possible bindings?
+  // it might just lead to inference variable hell not 100% sure if rustc does
+  // this i think the language might needs this to be explicitly set
+
+  SubstitutionArgumentMappings infer_arguments (std::move (args),
+						{} /* binding_arguments */,
+						locus);
+  return handle_substitions (std::move (infer_arguments));
+}
+
+SubstitutionArgumentMappings
+SubstitutionRef::adjust_mappings_for_this (
+  SubstitutionArgumentMappings &mappings)
+{
+  std::vector<SubstitutionArg> resolved_mappings;
+  for (size_t i = 0; i < substitutions.size (); i++)
+    {
+      auto &subst = substitutions.at (i);
+
+      SubstitutionArg arg = SubstitutionArg::error ();
+      if (mappings.size () == substitutions.size ())
+	{
+	  mappings.get_argument_at (i, &arg);
+	}
+      else
+	{
+	  if (subst.needs_substitution ())
+	    {
+	      // get from passed in mappings
+	      mappings.get_argument_for_symbol (subst.get_param_ty (), &arg);
+	    }
+	  else
+	    {
+	      // we should already have this somewhere
+	      used_arguments.get_argument_for_symbol (subst.get_param_ty (),
+						      &arg);
+	    }
+	}
+
+      bool ok = !arg.is_error ();
+      if (ok)
+	{
+	  SubstitutionArg adjusted (&subst, arg.get_tyty ());
+	  resolved_mappings.push_back (std::move (adjusted));
+	}
+    }
+
+  if (resolved_mappings.empty ())
+    return SubstitutionArgumentMappings::error ();
+
+  return SubstitutionArgumentMappings (resolved_mappings,
+				       mappings.get_binding_args (),
+				       mappings.get_locus (),
+				       mappings.get_subst_cb (),
+				       mappings.trait_item_mode ());
+}
+
+bool
+SubstitutionRef::are_mappings_bound (SubstitutionArgumentMappings &mappings)
+{
+  std::vector<SubstitutionArg> resolved_mappings;
+  for (size_t i = 0; i < substitutions.size (); i++)
+    {
+      auto &subst = substitutions.at (i);
+
+      SubstitutionArg arg = SubstitutionArg::error ();
+      if (mappings.size () == substitutions.size ())
+	{
+	  mappings.get_argument_at (i, &arg);
+	}
+      else
+	{
+	  if (subst.needs_substitution ())
+	    {
+	      // get from passed in mappings
+	      mappings.get_argument_for_symbol (subst.get_param_ty (), &arg);
+	    }
+	  else
+	    {
+	      // we should already have this somewhere
+	      used_arguments.get_argument_for_symbol (subst.get_param_ty (),
+						      &arg);
+	    }
+	}
+
+      bool ok = !arg.is_error ();
+      if (ok)
+	{
+	  SubstitutionArg adjusted (&subst, arg.get_tyty ());
+	  resolved_mappings.push_back (std::move (adjusted));
+	}
+    }
+
+  return !resolved_mappings.empty ();
+}
+
+// this function assumes that the mappings being passed are for the same type as
+// this new substitution reference so ordering matters here
+SubstitutionArgumentMappings
+SubstitutionRef::solve_mappings_from_receiver_for_self (
+  SubstitutionArgumentMappings &mappings) const
+{
+  std::vector<SubstitutionArg> resolved_mappings;
+
+  rust_assert (mappings.size () == get_num_substitutions ());
+  for (size_t i = 0; i < get_num_substitutions (); i++)
+    {
+      const SubstitutionParamMapping &param_mapping = substitutions.at (i);
+      SubstitutionArg &arg = mappings.get_mappings ().at (i);
+
+      if (param_mapping.needs_substitution ())
+	{
+	  SubstitutionArg adjusted (&param_mapping, arg.get_tyty ());
+	  resolved_mappings.push_back (std::move (adjusted));
+	}
+    }
+
+  return SubstitutionArgumentMappings (resolved_mappings,
+				       mappings.get_binding_args (),
+				       mappings.get_locus ());
+}
+
+SubstitutionArgumentMappings
+SubstitutionRef::solve_missing_mappings_from_this (SubstitutionRef &ref,
+						   SubstitutionRef &to)
+{
+  rust_assert (!ref.needs_substitution ());
+  rust_assert (needs_substitution ());
+  rust_assert (get_num_substitutions () == ref.get_num_substitutions ());
+
+  Location locus = used_arguments.get_locus ();
+  std::vector<SubstitutionArg> resolved_mappings;
+
+  std::map<HirId, std::pair<ParamType *, BaseType *>> substs;
+  for (size_t i = 0; i < get_num_substitutions (); i++)
+    {
+      SubstitutionParamMapping &a = substitutions.at (i);
+      SubstitutionParamMapping &b = ref.substitutions.at (i);
+
+      if (a.need_substitution ())
+	{
+	  const BaseType *root = a.get_param_ty ()->resolve ()->get_root ();
+	  rust_assert (root->get_kind () == TyTy::TypeKind::PARAM);
+	  const ParamType *p = static_cast<const TyTy::ParamType *> (root);
+
+	  substs[p->get_ty_ref ()] = {static_cast<ParamType *> (p->clone ()),
+				      b.get_param_ty ()->resolve ()};
+	}
+    }
+
+  for (auto it = substs.begin (); it != substs.end (); it++)
+    {
+      HirId param_id = it->first;
+      BaseType *arg = it->second.second;
+
+      const SubstitutionParamMapping *associate_param = nullptr;
+      for (SubstitutionParamMapping &p : to.substitutions)
+	{
+	  if (p.get_param_ty ()->get_ty_ref () == param_id)
+	    {
+	      associate_param = &p;
+	      break;
+	    }
+	}
+
+      rust_assert (associate_param != nullptr);
+      SubstitutionArg argument (associate_param, arg);
+      resolved_mappings.push_back (std::move (argument));
+    }
+
+  return SubstitutionArgumentMappings (resolved_mappings, {}, locus);
+}
+
+bool
+SubstitutionRef::monomorphize ()
+{
+  auto context = Resolver::TypeCheckContext::get ();
+  for (const auto &subst : get_substs ())
+    {
+      const TyTy::ParamType *pty = subst.get_param_ty ();
+
+      if (!pty->can_resolve ())
+	continue;
+
+      const TyTy::BaseType *binding = pty->resolve ();
+      if (binding->get_kind () == TyTy::TypeKind::PARAM)
+	continue;
+
+      for (const auto &bound : pty->get_specified_bounds ())
+	{
+	  const Resolver::TraitReference *specified_bound_ref = bound.get ();
+
+	  // setup any associated type mappings for the specified bonds and this
+	  // type
+	  auto candidates = Resolver::TypeBoundsProbe::Probe (binding);
+
+	  Resolver::AssociatedImplTrait *associated_impl_trait = nullptr;
+	  for (auto &probed_bound : candidates)
+	    {
+	      const Resolver::TraitReference *bound_trait_ref
+		= probed_bound.first;
+	      const HIR::ImplBlock *associated_impl = probed_bound.second;
+
+	      HirId impl_block_id
+		= associated_impl->get_mappings ().get_hirid ();
+	      Resolver::AssociatedImplTrait *associated = nullptr;
+	      bool found_impl_trait
+		= context->lookup_associated_trait_impl (impl_block_id,
+							 &associated);
+	      if (found_impl_trait)
+		{
+		  bool found_trait
+		    = specified_bound_ref->is_equal (*bound_trait_ref);
+		  bool found_self
+		    = associated->get_self ()->can_eq (binding, false);
+		  if (found_trait && found_self)
+		    {
+		      associated_impl_trait = associated;
+		      break;
+		    }
+		}
+	    }
+
+	  if (associated_impl_trait != nullptr)
+	    {
+	      associated_impl_trait->setup_associated_types (binding, bound);
+	    }
+	}
+    }
+
+  return true;
+}
+
+} // namespace TyTy
+} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-tyty-subst.h b/gcc/rust/typecheck/rust-tyty-subst.h
new file mode 100644
index 00000000000..4d09a3013e7
--- /dev/null
+++ b/gcc/rust/typecheck/rust-tyty-subst.h
@@ -0,0 +1,316 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_TYTY_SUBST_H
+#define RUST_TYTY_SUBST_H
+
+#include "rust-system.h"
+#include "rust-location.h"
+#include "rust-hir-full-decls.h"
+#include "rust-tyty-bounds.h"
+
+namespace Rust {
+namespace TyTy {
+
+class BaseType;
+class ParamType;
+class SubstitutionArgumentMappings;
+class SubstitutionParamMapping
+{
+public:
+  SubstitutionParamMapping (const HIR::TypeParam &generic, ParamType *param);
+
+  SubstitutionParamMapping (const SubstitutionParamMapping &other);
+
+  std::string as_string () const;
+
+  bool fill_param_ty (SubstitutionArgumentMappings &subst_mappings,
+		      Location locus);
+
+  SubstitutionParamMapping clone () const;
+
+  ParamType *get_param_ty ();
+
+  const ParamType *get_param_ty () const;
+
+  const HIR::TypeParam &get_generic_param ();
+
+  // this is used for the backend to override the HirId ref of the param to
+  // what the concrete type is for the rest of the context
+  void override_context ();
+
+  bool needs_substitution () const;
+
+  Location get_param_locus () const;
+
+  bool param_has_default_ty () const;
+
+  BaseType *get_default_ty () const;
+
+  bool need_substitution () const;
+
+private:
+  const HIR::TypeParam &generic;
+  ParamType *param;
+};
+
+class SubstitutionArg
+{
+public:
+  SubstitutionArg (const SubstitutionParamMapping *param, BaseType *argument);
+
+  // FIXME
+  // the copy constructors need removed - they are unsafe see
+  // TypeBoundPredicate
+  SubstitutionArg (const SubstitutionArg &other);
+
+  SubstitutionArg &operator= (const SubstitutionArg &other);
+
+  BaseType *get_tyty ();
+
+  const BaseType *get_tyty () const;
+
+  const SubstitutionParamMapping *get_param_mapping () const;
+
+  static SubstitutionArg error ();
+
+  bool is_error () const;
+
+  bool is_conrete () const;
+
+  std::string as_string () const;
+
+private:
+  const SubstitutionParamMapping *param;
+  BaseType *argument;
+};
+
+typedef std::function<void (const ParamType &, const SubstitutionArg &)>
+  ParamSubstCb;
+class SubstitutionArgumentMappings
+{
+public:
+  SubstitutionArgumentMappings (std::vector<SubstitutionArg> mappings,
+				std::map<std::string, BaseType *> binding_args,
+				Location locus,
+				ParamSubstCb param_subst_cb = nullptr,
+				bool trait_item_flag = false);
+
+  SubstitutionArgumentMappings (const SubstitutionArgumentMappings &other);
+  SubstitutionArgumentMappings &
+  operator= (const SubstitutionArgumentMappings &other);
+
+  SubstitutionArgumentMappings (SubstitutionArgumentMappings &&other) = default;
+  SubstitutionArgumentMappings &operator= (SubstitutionArgumentMappings &&other)
+    = default;
+
+  static SubstitutionArgumentMappings error ();
+
+  bool is_error () const;
+
+  bool get_argument_for_symbol (const ParamType *param_to_find,
+				SubstitutionArg *argument);
+
+  bool get_argument_at (size_t index, SubstitutionArg *argument);
+
+  // is_concrete means if the used args is non error, ie: non empty this will
+  // verify if actual real types have been put in place of are they still
+  // ParamTy
+  bool is_concrete () const;
+
+  Location get_locus () const;
+
+  size_t size () const;
+
+  bool is_empty () const;
+
+  std::vector<SubstitutionArg> &get_mappings ();
+
+  const std::vector<SubstitutionArg> &get_mappings () const;
+
+  std::map<std::string, BaseType *> &get_binding_args ();
+
+  const std::map<std::string, BaseType *> &get_binding_args () const;
+
+  std::string as_string () const;
+
+  void on_param_subst (const ParamType &p, const SubstitutionArg &a) const;
+
+  ParamSubstCb get_subst_cb () const;
+
+  bool trait_item_mode () const;
+
+private:
+  std::vector<SubstitutionArg> mappings;
+  std::map<std::string, BaseType *> binding_args;
+  Location locus;
+  ParamSubstCb param_subst_cb;
+  bool trait_item_flag;
+};
+
+class SubstitutionRef
+{
+public:
+  SubstitutionRef (std::vector<SubstitutionParamMapping> substitutions,
+		   SubstitutionArgumentMappings arguments);
+
+  bool has_substitutions () const;
+
+  std::string subst_as_string () const;
+
+  bool supports_associated_bindings () const;
+
+  // this is overridden in TypeBoundPredicate
+  // which support bindings we don't add them directly to the SubstitutionRef
+  // base class because this class represents the fn<X: Foo, Y: Bar>. The only
+  // construct which supports associated types
+  virtual size_t get_num_associated_bindings () const;
+
+  // this is overridden in TypeBoundPredicate
+  virtual TypeBoundPredicateItem
+  lookup_associated_type (const std::string &search);
+
+  size_t get_num_substitutions () const;
+
+  std::vector<SubstitutionParamMapping> &get_substs ();
+
+  const std::vector<SubstitutionParamMapping> &get_substs () const;
+
+  std::vector<SubstitutionParamMapping> clone_substs () const;
+
+  void override_context ();
+
+  bool needs_substitution () const;
+
+  bool was_substituted () const;
+
+  SubstitutionArgumentMappings get_substitution_arguments () const;
+
+  // this is the count of type params that are not substituted fuly
+  size_t num_required_substitutions () const;
+
+  // this is the count of type params that need substituted taking into account
+  // possible defaults
+  size_t min_required_substitutions () const;
+
+  // We are trying to subst <i32, f32> into Struct Foo<X,Y> {}
+  // in the case of Foo<i32,f32>{...}
+  //
+  // the substitions we have here define X,Y but the arguments have no bindings
+  // so its a matter of ordering
+  SubstitutionArgumentMappings
+  get_mappings_from_generic_args (HIR::GenericArgs &args);
+
+  // Recursive substitutions
+  // Foo <A,B> { a:A, b: B}; Bar <X,Y,Z>{a:X, b: Foo<Y,Z>}
+  //
+  // we have bindings for X Y Z and need to propagate the binding Y,Z into Foo
+  // Which binds to A,B
+  SubstitutionArgumentMappings
+  adjust_mappings_for_this (SubstitutionArgumentMappings &mappings);
+
+  // Are the mappings here actually bound to this type. For example imagine the
+  // case:
+  //
+  // struct Foo<T>(T);
+  // impl<T> Foo<T> {
+  //   fn test(self) { ... }
+  // }
+  //
+  // In this case we have a generic ADT of Foo and an impl block of a generic T
+  // on Foo for the Self type. When we it comes to path resolution we can have:
+  //
+  // Foo::<i32>::test()
+  //
+  // This means the first segment of Foo::<i32> returns the ADT Foo<i32> not the
+  // Self ADT bound to the T from the impl block. This means when it comes to
+  // the next segment of test which resolves to the function we need to check
+  // wether the arguments in the struct definition of foo can be bound here
+  // before substituting the previous segments type here. This functions acts as
+  // a guard for the solve_mappings_from_receiver_for_self to handle the case
+  // where arguments are not bound. This is important for this next case:
+  //
+  // struct Baz<A, B>(A, B);
+  // impl Baz<i32, f32> {
+  //   fn test<X>(a: X) -> X {
+  //       a
+  //   }
+  // }
+  //
+  // In this case Baz has been already substituted for the impl's Self to become
+  // ADT<i32, f32> so that the function test only has 1 generic argument of X.
+  // The path for this will be:
+  //
+  // Baz::test::<_>(123)
+  //
+  // So the first segment here will be Baz<_, _> to try and infer the arguments
+  // which will be taken from the impl's Self type in this case since it is
+  // already substituted and like the previous case the check to see if we need
+  // to inherit the previous segments generic arguments takes place but the
+  // generic arguments are not bound to this type as they have already been
+  // substituted.
+  //
+  // Its important to remember from the first example the FnType actually looks
+  // like:
+  //
+  // fn <T>test(self :Foo<T>(T))
+  //
+  // As the generic parameters are "bound" to each of the items in the impl
+  // block. So this check is about wether the arguments we have here can
+  // actually be bound to this type.
+  bool are_mappings_bound (SubstitutionArgumentMappings &mappings);
+
+  // struct Foo<A, B>(A, B);
+  //
+  // impl<T> Foo<T, f32>;
+  //     -> fn test<X>(self, a: X) -> X
+  //
+  // We might invoke this via:
+  //
+  // a = Foo(123, 456f32);
+  // b = a.test::<bool>(false);
+  //
+  // we need to figure out relevant generic arguemts for self to apply to the
+  // fntype
+  SubstitutionArgumentMappings solve_mappings_from_receiver_for_self (
+    SubstitutionArgumentMappings &mappings) const;
+
+  // TODO comment
+  SubstitutionArgumentMappings
+  solve_missing_mappings_from_this (SubstitutionRef &ref, SubstitutionRef &to);
+
+  // TODO comment
+  BaseType *infer_substitions (Location locus);
+
+  // TODO comment
+  bool monomorphize ();
+
+  // TODO comment
+  virtual BaseType *handle_substitions (SubstitutionArgumentMappings mappings)
+    = 0;
+
+  SubstitutionArgumentMappings get_used_arguments () const;
+
+protected:
+  std::vector<SubstitutionParamMapping> substitutions;
+  SubstitutionArgumentMappings used_arguments;
+};
+
+} // namespace TyTy
+} // namespace Rust
+#endif // RUST_TYTY_SUBST_H
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 55a8123ce87..b45bd99b1bd 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -514,472 +514,6 @@ StructFieldType::monomorphized_clone () const
 			      get_field_type ()->monomorphized_clone (), locus);
 }
 
-bool
-SubstitutionParamMapping::need_substitution () const
-{
-  if (!param->can_resolve ())
-    return true;
-
-  auto resolved = param->resolve ();
-  return !resolved->is_concrete ();
-}
-
-bool
-SubstitutionParamMapping::fill_param_ty (
-  SubstitutionArgumentMappings &subst_mappings, Location locus)
-{
-  SubstitutionArg arg = SubstitutionArg::error ();
-  bool ok = subst_mappings.get_argument_for_symbol (get_param_ty (), &arg);
-  if (!ok)
-    return true;
-
-  TyTy::BaseType &type = *arg.get_tyty ();
-  if (type.get_kind () == TyTy::TypeKind::INFER)
-    {
-      type.inherit_bounds (*param);
-    }
-  else
-    {
-      if (!param->bounds_compatible (type, locus, true))
-	return false;
-    }
-
-  if (type.get_kind () == TypeKind::PARAM)
-    {
-      // delete param;
-      param = static_cast<ParamType *> (type.clone ());
-    }
-  else
-    {
-      // check the substitution is compatible with bounds
-      if (!param->bounds_compatible (type, locus, true))
-	return false;
-
-      // recursively pass this down to all HRTB's
-      for (auto &bound : param->get_specified_bounds ())
-	bound.handle_substitions (subst_mappings);
-
-      param->set_ty_ref (type.get_ref ());
-    }
-
-  return true;
-}
-
-void
-SubstitutionParamMapping::override_context ()
-{
-  if (!param->can_resolve ())
-    return;
-
-  auto mappings = Analysis::Mappings::get ();
-  auto context = Resolver::TypeCheckContext::get ();
-
-  context->insert_type (Analysis::NodeMapping (mappings->get_current_crate (),
-					       UNKNOWN_NODEID,
-					       param->get_ref (),
-					       UNKNOWN_LOCAL_DEFID),
-			param->resolve ());
-}
-
-SubstitutionArgumentMappings
-SubstitutionRef::get_mappings_from_generic_args (HIR::GenericArgs &args)
-{
-  std::map<std::string, BaseType *> binding_arguments;
-  if (args.get_binding_args ().size () > 0)
-    {
-      if (supports_associated_bindings ())
-	{
-	  if (args.get_binding_args ().size () > get_num_associated_bindings ())
-	    {
-	      RichLocation r (args.get_locus ());
-
-	      rust_error_at (r,
-			     "generic item takes at most %lu type binding "
-			     "arguments but %lu were supplied",
-			     (unsigned long) get_num_associated_bindings (),
-			     (unsigned long) args.get_binding_args ().size ());
-	      return SubstitutionArgumentMappings::error ();
-	    }
-
-	  for (auto &binding : args.get_binding_args ())
-	    {
-	      BaseType *resolved
-		= Resolver::TypeCheckType::Resolve (binding.get_type ().get ());
-	      if (resolved == nullptr
-		  || resolved->get_kind () == TyTy::TypeKind::ERROR)
-		{
-		  rust_error_at (binding.get_locus (),
-				 "failed to resolve type arguments");
-		  return SubstitutionArgumentMappings::error ();
-		}
-
-	      // resolve to relevant binding
-	      auto binding_item
-		= lookup_associated_type (binding.get_identifier ());
-	      if (binding_item.is_error ())
-		{
-		  rust_error_at (binding.get_locus (),
-				 "unknown associated type binding: %s",
-				 binding.get_identifier ().c_str ());
-		  return SubstitutionArgumentMappings::error ();
-		}
-
-	      binding_arguments[binding.get_identifier ()] = resolved;
-	    }
-	}
-      else
-	{
-	  RichLocation r (args.get_locus ());
-	  for (auto &binding : args.get_binding_args ())
-	    r.add_range (binding.get_locus ());
-
-	  rust_error_at (r, "associated type bindings are not allowed here");
-	  return SubstitutionArgumentMappings::error ();
-	}
-    }
-
-  // for inherited arguments
-  size_t offs = used_arguments.size ();
-  if (args.get_type_args ().size () + offs > substitutions.size ())
-    {
-      RichLocation r (args.get_locus ());
-      r.add_range (substitutions.front ().get_param_locus ());
-
-      rust_error_at (
-	r,
-	"generic item takes at most %lu type arguments but %lu were supplied",
-	(unsigned long) substitutions.size (),
-	(unsigned long) args.get_type_args ().size ());
-      return SubstitutionArgumentMappings::error ();
-    }
-
-  if (args.get_type_args ().size () + offs < min_required_substitutions ())
-    {
-      RichLocation r (args.get_locus ());
-      r.add_range (substitutions.front ().get_param_locus ());
-
-      rust_error_at (
-	r,
-	"generic item takes at least %lu type arguments but %lu were supplied",
-	(unsigned long) (min_required_substitutions () - offs),
-	(unsigned long) args.get_type_args ().size ());
-      return SubstitutionArgumentMappings::error ();
-    }
-
-  std::vector<SubstitutionArg> mappings = used_arguments.get_mappings ();
-  for (auto &arg : args.get_type_args ())
-    {
-      BaseType *resolved = Resolver::TypeCheckType::Resolve (arg.get ());
-      if (resolved == nullptr || resolved->get_kind () == TyTy::TypeKind::ERROR)
-	{
-	  rust_error_at (args.get_locus (), "failed to resolve type arguments");
-	  return SubstitutionArgumentMappings::error ();
-	}
-
-      SubstitutionArg subst_arg (&substitutions.at (offs), resolved);
-      offs++;
-      mappings.push_back (std::move (subst_arg));
-    }
-
-  // we must need to fill out defaults
-  size_t left_over
-    = num_required_substitutions () - min_required_substitutions ();
-  if (left_over > 0)
-    {
-      for (size_t offs = mappings.size (); offs < substitutions.size (); offs++)
-	{
-	  SubstitutionParamMapping &param = substitutions.at (offs);
-	  rust_assert (param.param_has_default_ty ());
-
-	  BaseType *resolved = param.get_default_ty ();
-	  if (resolved->get_kind () == TypeKind::ERROR)
-	    return SubstitutionArgumentMappings::error ();
-
-	  // this resolved default might already contain default parameters
-	  if (resolved->contains_type_parameters ())
-	    {
-	      SubstitutionArgumentMappings intermediate (mappings,
-							 binding_arguments,
-							 args.get_locus ());
-	      resolved = Resolver::SubstMapperInternal::Resolve (resolved,
-								 intermediate);
-
-	      if (resolved->get_kind () == TypeKind::ERROR)
-		return SubstitutionArgumentMappings::error ();
-	    }
-
-	  SubstitutionArg subst_arg (&param, resolved);
-	  mappings.push_back (std::move (subst_arg));
-	}
-    }
-
-  return SubstitutionArgumentMappings (mappings, binding_arguments,
-				       args.get_locus ());
-}
-
-BaseType *
-SubstitutionRef::infer_substitions (Location locus)
-{
-  std::vector<SubstitutionArg> args;
-  std::map<std::string, BaseType *> argument_mappings;
-  for (auto &p : get_substs ())
-    {
-      if (p.needs_substitution ())
-	{
-	  const std::string &symbol = p.get_param_ty ()->get_symbol ();
-	  auto it = argument_mappings.find (symbol);
-	  bool have_mapping = it != argument_mappings.end ();
-
-	  if (have_mapping)
-	    {
-	      args.push_back (SubstitutionArg (&p, it->second));
-	    }
-	  else
-	    {
-	      TyVar infer_var = TyVar::get_implicit_infer_var (locus);
-	      args.push_back (SubstitutionArg (&p, infer_var.get_tyty ()));
-	      argument_mappings[symbol] = infer_var.get_tyty ();
-	    }
-	}
-      else
-	{
-	  args.push_back (SubstitutionArg (&p, p.get_param_ty ()->resolve ()));
-	}
-    }
-
-  // FIXME do we need to add inference variables to all the possible bindings?
-  // it might just lead to inference variable hell not 100% sure if rustc does
-  // this i think the language might needs this to be explicitly set
-
-  SubstitutionArgumentMappings infer_arguments (std::move (args),
-						{} /* binding_arguments */,
-						locus);
-  return handle_substitions (std::move (infer_arguments));
-}
-
-SubstitutionArgumentMappings
-SubstitutionRef::adjust_mappings_for_this (
-  SubstitutionArgumentMappings &mappings)
-{
-  std::vector<SubstitutionArg> resolved_mappings;
-  for (size_t i = 0; i < substitutions.size (); i++)
-    {
-      auto &subst = substitutions.at (i);
-
-      SubstitutionArg arg = SubstitutionArg::error ();
-      if (mappings.size () == substitutions.size ())
-	{
-	  mappings.get_argument_at (i, &arg);
-	}
-      else
-	{
-	  if (subst.needs_substitution ())
-	    {
-	      // get from passed in mappings
-	      mappings.get_argument_for_symbol (subst.get_param_ty (), &arg);
-	    }
-	  else
-	    {
-	      // we should already have this somewhere
-	      used_arguments.get_argument_for_symbol (subst.get_param_ty (),
-						      &arg);
-	    }
-	}
-
-      bool ok = !arg.is_error ();
-      if (ok)
-	{
-	  SubstitutionArg adjusted (&subst, arg.get_tyty ());
-	  resolved_mappings.push_back (std::move (adjusted));
-	}
-    }
-
-  if (resolved_mappings.empty ())
-    return SubstitutionArgumentMappings::error ();
-
-  return SubstitutionArgumentMappings (resolved_mappings,
-				       mappings.get_binding_args (),
-				       mappings.get_locus (),
-				       mappings.get_subst_cb (),
-				       mappings.trait_item_mode ());
-}
-
-bool
-SubstitutionRef::are_mappings_bound (SubstitutionArgumentMappings &mappings)
-{
-  std::vector<SubstitutionArg> resolved_mappings;
-  for (size_t i = 0; i < substitutions.size (); i++)
-    {
-      auto &subst = substitutions.at (i);
-
-      SubstitutionArg arg = SubstitutionArg::error ();
-      if (mappings.size () == substitutions.size ())
-	{
-	  mappings.get_argument_at (i, &arg);
-	}
-      else
-	{
-	  if (subst.needs_substitution ())
-	    {
-	      // get from passed in mappings
-	      mappings.get_argument_for_symbol (subst.get_param_ty (), &arg);
-	    }
-	  else
-	    {
-	      // we should already have this somewhere
-	      used_arguments.get_argument_for_symbol (subst.get_param_ty (),
-						      &arg);
-	    }
-	}
-
-      bool ok = !arg.is_error ();
-      if (ok)
-	{
-	  SubstitutionArg adjusted (&subst, arg.get_tyty ());
-	  resolved_mappings.push_back (std::move (adjusted));
-	}
-    }
-
-  return !resolved_mappings.empty ();
-}
-
-// this function assumes that the mappings being passed are for the same type as
-// this new substitution reference so ordering matters here
-SubstitutionArgumentMappings
-SubstitutionRef::solve_mappings_from_receiver_for_self (
-  SubstitutionArgumentMappings &mappings) const
-{
-  std::vector<SubstitutionArg> resolved_mappings;
-
-  rust_assert (mappings.size () == get_num_substitutions ());
-  for (size_t i = 0; i < get_num_substitutions (); i++)
-    {
-      const SubstitutionParamMapping &param_mapping = substitutions.at (i);
-      SubstitutionArg &arg = mappings.get_mappings ().at (i);
-
-      if (param_mapping.needs_substitution ())
-	{
-	  SubstitutionArg adjusted (&param_mapping, arg.get_tyty ());
-	  resolved_mappings.push_back (std::move (adjusted));
-	}
-    }
-
-  return SubstitutionArgumentMappings (resolved_mappings,
-				       mappings.get_binding_args (),
-				       mappings.get_locus ());
-}
-
-SubstitutionArgumentMappings
-SubstitutionRef::solve_missing_mappings_from_this (SubstitutionRef &ref,
-						   SubstitutionRef &to)
-{
-  rust_assert (!ref.needs_substitution ());
-  rust_assert (needs_substitution ());
-  rust_assert (get_num_substitutions () == ref.get_num_substitutions ());
-
-  Location locus = used_arguments.get_locus ();
-  std::vector<SubstitutionArg> resolved_mappings;
-
-  std::map<HirId, std::pair<ParamType *, BaseType *>> substs;
-  for (size_t i = 0; i < get_num_substitutions (); i++)
-    {
-      SubstitutionParamMapping &a = substitutions.at (i);
-      SubstitutionParamMapping &b = ref.substitutions.at (i);
-
-      if (a.need_substitution ())
-	{
-	  const BaseType *root = a.get_param_ty ()->resolve ()->get_root ();
-	  rust_assert (root->get_kind () == TyTy::TypeKind::PARAM);
-	  const ParamType *p = static_cast<const TyTy::ParamType *> (root);
-
-	  substs[p->get_ty_ref ()] = {static_cast<ParamType *> (p->clone ()),
-				      b.get_param_ty ()->resolve ()};
-	}
-    }
-
-  for (auto it = substs.begin (); it != substs.end (); it++)
-    {
-      HirId param_id = it->first;
-      BaseType *arg = it->second.second;
-
-      const SubstitutionParamMapping *associate_param = nullptr;
-      for (SubstitutionParamMapping &p : to.substitutions)
-	{
-	  if (p.get_param_ty ()->get_ty_ref () == param_id)
-	    {
-	      associate_param = &p;
-	      break;
-	    }
-	}
-
-      rust_assert (associate_param != nullptr);
-      SubstitutionArg argument (associate_param, arg);
-      resolved_mappings.push_back (std::move (argument));
-    }
-
-  return SubstitutionArgumentMappings (resolved_mappings, {}, locus);
-}
-
-bool
-SubstitutionRef::monomorphize ()
-{
-  auto context = Resolver::TypeCheckContext::get ();
-  for (const auto &subst : get_substs ())
-    {
-      const TyTy::ParamType *pty = subst.get_param_ty ();
-
-      if (!pty->can_resolve ())
-	continue;
-
-      const TyTy::BaseType *binding = pty->resolve ();
-      if (binding->get_kind () == TyTy::TypeKind::PARAM)
-	continue;
-
-      for (const auto &bound : pty->get_specified_bounds ())
-	{
-	  const Resolver::TraitReference *specified_bound_ref = bound.get ();
-
-	  // setup any associated type mappings for the specified bonds and this
-	  // type
-	  auto candidates = Resolver::TypeBoundsProbe::Probe (binding);
-
-	  Resolver::AssociatedImplTrait *associated_impl_trait = nullptr;
-	  for (auto &probed_bound : candidates)
-	    {
-	      const Resolver::TraitReference *bound_trait_ref
-		= probed_bound.first;
-	      const HIR::ImplBlock *associated_impl = probed_bound.second;
-
-	      HirId impl_block_id
-		= associated_impl->get_mappings ().get_hirid ();
-	      Resolver::AssociatedImplTrait *associated = nullptr;
-	      bool found_impl_trait
-		= context->lookup_associated_trait_impl (impl_block_id,
-							 &associated);
-	      if (found_impl_trait)
-		{
-		  bool found_trait
-		    = specified_bound_ref->is_equal (*bound_trait_ref);
-		  bool found_self
-		    = associated->get_self ()->can_eq (binding, false);
-		  if (found_trait && found_self)
-		    {
-		      associated_impl_trait = associated;
-		      break;
-		    }
-		}
-	    }
-
-	  if (associated_impl_trait != nullptr)
-	    {
-	      associated_impl_trait->setup_associated_types (binding, bound);
-	    }
-	}
-    }
-
-  return true;
-}
-
 void
 ADTType::accept_vis (TyVisitor &vis)
 {
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index a8bdf6f3a15..cb30a60ae96 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -27,6 +27,7 @@
 #include "rust-identifier.h"
 #include "rust-tyty-bounds.h"
 #include "rust-tyty-util.h"
+#include "rust-tyty-subst.h"
 
 namespace Rust {
 
@@ -462,469 +463,6 @@ private:
   std::vector<TyVar> fields;
 };
 
-class SubstitutionParamMapping
-{
-public:
-  SubstitutionParamMapping (const HIR::TypeParam &generic, ParamType *param)
-    : generic (generic), param (param)
-  {}
-
-  SubstitutionParamMapping (const SubstitutionParamMapping &other)
-    : generic (other.generic), param (other.param)
-  {}
-
-  std::string as_string () const
-  {
-    if (param == nullptr)
-      return "nullptr";
-
-    return param->get_name ();
-  }
-
-  bool fill_param_ty (SubstitutionArgumentMappings &subst_mappings,
-		      Location locus);
-
-  SubstitutionParamMapping clone () const
-  {
-    return SubstitutionParamMapping (generic, static_cast<ParamType *> (
-						param->clone ()));
-  }
-
-  ParamType *get_param_ty () { return param; }
-
-  const ParamType *get_param_ty () const { return param; }
-
-  const HIR::TypeParam &get_generic_param () { return generic; };
-
-  // this is used for the backend to override the HirId ref of the param to
-  // what the concrete type is for the rest of the context
-  void override_context ();
-
-  bool needs_substitution () const
-  {
-    return !(get_param_ty ()->is_concrete ());
-  }
-
-  Location get_param_locus () const { return generic.get_locus (); }
-
-  bool param_has_default_ty () const { return generic.has_type (); }
-
-  BaseType *get_default_ty () const
-  {
-    TyVar var (generic.get_type_mappings ().get_hirid ());
-    return var.get_tyty ();
-  }
-
-  bool need_substitution () const;
-
-private:
-  const HIR::TypeParam &generic;
-  ParamType *param;
-};
-
-class SubstitutionArg
-{
-public:
-  SubstitutionArg (const SubstitutionParamMapping *param, BaseType *argument)
-    : param (param), argument (argument)
-  {}
-
-  // FIXME
-  // the copy constructors need removed - they are unsafe see
-  // TypeBoundPredicate
-  SubstitutionArg (const SubstitutionArg &other)
-    : param (other.param), argument (other.argument)
-  {}
-
-  SubstitutionArg &operator= (const SubstitutionArg &other)
-  {
-    param = other.param;
-    argument = other.argument;
-    return *this;
-  }
-
-  BaseType *get_tyty () { return argument; }
-
-  const BaseType *get_tyty () const { return argument; }
-
-  const SubstitutionParamMapping *get_param_mapping () const { return param; }
-
-  static SubstitutionArg error () { return SubstitutionArg (nullptr, nullptr); }
-
-  bool is_error () const { return param == nullptr || argument == nullptr; }
-
-  bool is_conrete () const
-  {
-    if (argument != nullptr)
-      return true;
-
-    if (argument->get_kind () == TyTy::TypeKind::PARAM)
-      return false;
-
-    return argument->is_concrete ();
-  }
-
-  std::string as_string () const
-  {
-    return param->as_string ()
-	   + (argument != nullptr ? ":" + argument->as_string () : "");
-  }
-
-private:
-  const SubstitutionParamMapping *param;
-  BaseType *argument;
-};
-
-typedef std::function<void (const ParamType &, const SubstitutionArg &)>
-  ParamSubstCb;
-class SubstitutionArgumentMappings
-{
-public:
-  SubstitutionArgumentMappings (std::vector<SubstitutionArg> mappings,
-				std::map<std::string, BaseType *> binding_args,
-				Location locus,
-				ParamSubstCb param_subst_cb = nullptr,
-				bool trait_item_flag = false)
-    : mappings (mappings), binding_args (binding_args), locus (locus),
-      param_subst_cb (param_subst_cb), trait_item_flag (trait_item_flag)
-  {}
-
-  SubstitutionArgumentMappings (const SubstitutionArgumentMappings &other)
-    : mappings (other.mappings), binding_args (other.binding_args),
-      locus (other.locus), param_subst_cb (other.param_subst_cb),
-      trait_item_flag (other.trait_item_flag)
-  {}
-
-  SubstitutionArgumentMappings &
-  operator= (const SubstitutionArgumentMappings &other)
-  {
-    mappings = other.mappings;
-    binding_args = other.binding_args;
-    locus = other.locus;
-    param_subst_cb = other.param_subst_cb;
-    trait_item_flag = other.trait_item_flag;
-
-    return *this;
-  }
-
-  SubstitutionArgumentMappings (SubstitutionArgumentMappings &&other) = default;
-  SubstitutionArgumentMappings &operator= (SubstitutionArgumentMappings &&other)
-    = default;
-
-  static SubstitutionArgumentMappings error ()
-  {
-    return SubstitutionArgumentMappings ({}, {}, Location (), nullptr, false);
-  }
-
-  bool is_error () const { return mappings.size () == 0; }
-
-  bool get_argument_for_symbol (const ParamType *param_to_find,
-				SubstitutionArg *argument)
-  {
-    for (auto &mapping : mappings)
-      {
-	const SubstitutionParamMapping *param = mapping.get_param_mapping ();
-	const ParamType *p = param->get_param_ty ();
-
-	if (p->get_symbol ().compare (param_to_find->get_symbol ()) == 0)
-	  {
-	    *argument = mapping;
-	    return true;
-	  }
-      }
-    return false;
-  }
-
-  bool get_argument_at (size_t index, SubstitutionArg *argument)
-  {
-    if (index > mappings.size ())
-      return false;
-
-    *argument = mappings.at (index);
-    return true;
-  }
-
-  // is_concrete means if the used args is non error, ie: non empty this will
-  // verify if actual real types have been put in place of are they still
-  // ParamTy
-  bool is_concrete () const
-  {
-    for (auto &mapping : mappings)
-      {
-	if (!mapping.is_conrete ())
-	  return false;
-      }
-    return true;
-  }
-
-  Location get_locus () const { return locus; }
-
-  size_t size () const { return mappings.size (); }
-
-  bool is_empty () const { return size () == 0; }
-
-  std::vector<SubstitutionArg> &get_mappings () { return mappings; }
-
-  const std::vector<SubstitutionArg> &get_mappings () const { return mappings; }
-
-  std::map<std::string, BaseType *> &get_binding_args ()
-  {
-    return binding_args;
-  }
-
-  const std::map<std::string, BaseType *> &get_binding_args () const
-  {
-    return binding_args;
-  }
-
-  std::string as_string () const
-  {
-    std::string buffer;
-    for (auto &mapping : mappings)
-      {
-	buffer += mapping.as_string () + ", ";
-      }
-    return "<" + buffer + ">";
-  }
-
-  void on_param_subst (const ParamType &p, const SubstitutionArg &a) const
-  {
-    if (param_subst_cb == nullptr)
-      return;
-
-    param_subst_cb (p, a);
-  }
-
-  ParamSubstCb get_subst_cb () const { return param_subst_cb; }
-
-  bool trait_item_mode () const { return trait_item_flag; }
-
-private:
-  std::vector<SubstitutionArg> mappings;
-  std::map<std::string, BaseType *> binding_args;
-  Location locus;
-  ParamSubstCb param_subst_cb;
-  bool trait_item_flag;
-};
-
-class SubstitutionRef
-{
-public:
-  SubstitutionRef (std::vector<SubstitutionParamMapping> substitutions,
-		   SubstitutionArgumentMappings arguments)
-    : substitutions (substitutions), used_arguments (arguments)
-  {}
-
-  bool has_substitutions () const { return substitutions.size () > 0; }
-
-  std::string subst_as_string () const
-  {
-    std::string buffer;
-    for (size_t i = 0; i < substitutions.size (); i++)
-      {
-	const SubstitutionParamMapping &sub = substitutions.at (i);
-	buffer += sub.as_string ();
-
-	if ((i + 1) < substitutions.size ())
-	  buffer += ", ";
-      }
-
-    return buffer.empty () ? "" : "<" + buffer + ">";
-  }
-
-  bool supports_associated_bindings () const
-  {
-    return get_num_associated_bindings () > 0;
-  }
-
-  // this is overridden in TypeBoundPredicate
-  // which support bindings we don't add them directly to the SubstitutionRef
-  // base class because this class represents the fn<X: Foo, Y: Bar>. The only
-  // construct which supports associated types
-  virtual size_t get_num_associated_bindings () const { return 0; }
-
-  // this is overridden in TypeBoundPredicate
-  virtual TypeBoundPredicateItem
-  lookup_associated_type (const std::string &search)
-  {
-    return TypeBoundPredicateItem::error ();
-  }
-
-  size_t get_num_substitutions () const { return substitutions.size (); }
-
-  std::vector<SubstitutionParamMapping> &get_substs () { return substitutions; }
-
-  const std::vector<SubstitutionParamMapping> &get_substs () const
-  {
-    return substitutions;
-  }
-
-  std::vector<SubstitutionParamMapping> clone_substs () const
-  {
-    std::vector<SubstitutionParamMapping> clone;
-
-    for (auto &sub : substitutions)
-      clone.push_back (sub.clone ());
-
-    return clone;
-  }
-
-  void override_context ()
-  {
-    for (auto &sub : substitutions)
-      {
-	sub.override_context ();
-      }
-  }
-
-  bool needs_substitution () const
-  {
-    for (auto &sub : substitutions)
-      {
-	if (sub.need_substitution ())
-	  return true;
-      }
-    return false;
-  }
-
-  bool was_substituted () const { return !needs_substitution (); }
-
-  SubstitutionArgumentMappings get_substitution_arguments () const
-  {
-    return used_arguments;
-  }
-
-  // this is the count of type params that are not substituted fuly
-  size_t num_required_substitutions () const
-  {
-    size_t n = 0;
-    for (auto &p : substitutions)
-      {
-	if (p.needs_substitution ())
-	  n++;
-      }
-    return n;
-  }
-
-  // this is the count of type params that need substituted taking into account
-  // possible defaults
-  size_t min_required_substitutions () const
-  {
-    size_t n = 0;
-    for (auto &p : substitutions)
-      {
-	if (p.needs_substitution () && !p.param_has_default_ty ())
-	  n++;
-      }
-    return n;
-  }
-
-  // We are trying to subst <i32, f32> into Struct Foo<X,Y> {}
-  // in the case of Foo<i32,f32>{...}
-  //
-  // the substitions we have here define X,Y but the arguments have no bindings
-  // so its a matter of ordering
-  SubstitutionArgumentMappings
-  get_mappings_from_generic_args (HIR::GenericArgs &args);
-
-  // Recursive substitutions
-  // Foo <A,B> { a:A, b: B}; Bar <X,Y,Z>{a:X, b: Foo<Y,Z>}
-  //
-  // we have bindings for X Y Z and need to propagate the binding Y,Z into Foo
-  // Which binds to A,B
-  SubstitutionArgumentMappings
-  adjust_mappings_for_this (SubstitutionArgumentMappings &mappings);
-
-  // Are the mappings here actually bound to this type. For example imagine the
-  // case:
-  //
-  // struct Foo<T>(T);
-  // impl<T> Foo<T> {
-  //   fn test(self) { ... }
-  // }
-  //
-  // In this case we have a generic ADT of Foo and an impl block of a generic T
-  // on Foo for the Self type. When we it comes to path resolution we can have:
-  //
-  // Foo::<i32>::test()
-  //
-  // This means the first segment of Foo::<i32> returns the ADT Foo<i32> not the
-  // Self ADT bound to the T from the impl block. This means when it comes to
-  // the next segment of test which resolves to the function we need to check
-  // wether the arguments in the struct definition of foo can be bound here
-  // before substituting the previous segments type here. This functions acts as
-  // a guard for the solve_mappings_from_receiver_for_self to handle the case
-  // where arguments are not bound. This is important for this next case:
-  //
-  // struct Baz<A, B>(A, B);
-  // impl Baz<i32, f32> {
-  //   fn test<X>(a: X) -> X {
-  //       a
-  //   }
-  // }
-  //
-  // In this case Baz has been already substituted for the impl's Self to become
-  // ADT<i32, f32> so that the function test only has 1 generic argument of X.
-  // The path for this will be:
-  //
-  // Baz::test::<_>(123)
-  //
-  // So the first segment here will be Baz<_, _> to try and infer the arguments
-  // which will be taken from the impl's Self type in this case since it is
-  // already substituted and like the previous case the check to see if we need
-  // to inherit the previous segments generic arguments takes place but the
-  // generic arguments are not bound to this type as they have already been
-  // substituted.
-  //
-  // Its important to remember from the first example the FnType actually looks
-  // like:
-  //
-  // fn <T>test(self :Foo<T>(T))
-  //
-  // As the generic parameters are "bound" to each of the items in the impl
-  // block. So this check is about wether the arguments we have here can
-  // actually be bound to this type.
-  bool are_mappings_bound (SubstitutionArgumentMappings &mappings);
-
-  // struct Foo<A, B>(A, B);
-  //
-  // impl<T> Foo<T, f32>;
-  //     -> fn test<X>(self, a: X) -> X
-  //
-  // We might invoke this via:
-  //
-  // a = Foo(123, 456f32);
-  // b = a.test::<bool>(false);
-  //
-  // we need to figure out relevant generic arguemts for self to apply to the
-  // fntype
-  SubstitutionArgumentMappings solve_mappings_from_receiver_for_self (
-    SubstitutionArgumentMappings &mappings) const;
-
-  // TODO comment
-  SubstitutionArgumentMappings
-  solve_missing_mappings_from_this (SubstitutionRef &ref, SubstitutionRef &to);
-
-  // TODO comment
-  BaseType *infer_substitions (Location locus);
-
-  // TODO comment
-  bool monomorphize ();
-
-  // TODO comment
-  virtual BaseType *handle_substitions (SubstitutionArgumentMappings mappings)
-    = 0;
-
-  SubstitutionArgumentMappings get_used_arguments () const
-  {
-    return used_arguments;
-  }
-
-protected:
-  std::vector<SubstitutionParamMapping> substitutions;
-  SubstitutionArgumentMappings used_arguments;
-};
-
 class TypeBoundPredicate : public SubstitutionRef
 {
 public:
-- 
2.40.0


  parent reply	other threads:[~2023-04-05 14:05 UTC|newest]

Thread overview: 92+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-05 14:02 Rust front-end update 2023-04-05 arthur.cohen
2023-04-05 14:02 ` [committed 01/88] gccrs: fatal_error_flag: Fix typo in error message arthur.cohen
2023-04-05 14:02 ` [committed 02/88] gccrs: unsafe: check use of `target_feature` attribute arthur.cohen
2023-04-05 14:02 ` [committed 03/88] gccrs: Check for mutable references in const functions arthur.cohen
2023-04-05 14:02 ` [committed 04/88] gccrs: rust: add bound parsing in parse_generic_arg arthur.cohen
2023-04-05 14:02 ` [committed 05/88] gccrs: Implement declarative macro 2.0 parser arthur.cohen
2023-04-05 14:02 ` [committed 06/88] gccrs: Add name resolution to generic argument associated item bindings arthur.cohen
2023-04-05 14:02 ` [committed 07/88] gccrs: Support associated type bound arguments arthur.cohen
2023-04-05 14:02 ` [committed 08/88] gccrs: Reuse TypeCheckPattern on LetStmt's arthur.cohen
2023-04-05 14:02 ` [committed 09/88] gccrs: Add get_locus function for abstract class MetaItemInner arthur.cohen
2023-04-05 14:02 ` [committed 10/88] gccrs: diagnostics: Add underline for tokens in diagnostics arthur.cohen
2023-04-05 14:02 ` [committed 11/88] gccrs: Change how CompileVarDecl outputs Bvariable's arthur.cohen
2023-04-05 14:02 ` [committed 12/88] gccrs: testsuite: Handle Windows carriage returns properly arthur.cohen
2023-04-05 14:02 ` [committed 13/88] gccrs: Support GroupedPattern during name resolution arthur.cohen
2023-04-05 14:02 ` [committed 14/88] gccrs: Do not crash on empty macros expand. Fixes #1712 arthur.cohen
2023-04-05 14:02 ` [committed 15/88] gccrs: Add HIR lowering for GroupedPattern arthur.cohen
2023-04-05 14:03 ` [committed 16/88] gccrs: Add get_item method for HIR::GroupedPattern arthur.cohen
2023-04-05 14:03 ` [committed 17/88] gccrs: Add type resolution for grouped patterns arthur.cohen
2023-04-05 14:03 ` [committed 18/88] gccrs: Added missing GroupedPattern visitors for code generation arthur.cohen
2023-04-05 14:03 ` [committed 19/88] gccrs: Rename file rust-ast-full-test.cc to rust-ast.cc arthur.cohen
2023-04-05 14:03 ` [committed 20/88] gccrs: moved operator.h to util/rust-operators.h arthur.cohen
2023-04-05 14:03 ` [committed 21/88] gccrs: fixed compiler error message on wildcard pattern within expression arthur.cohen
2023-04-05 14:03 ` [committed 22/88] gccrs: fixed indentations in AST pretty expanded dump of trait arthur.cohen
2023-04-05 14:03 ` [committed 23/88] gccrs: macro: Allow builtin `MacroInvocation`s within the AST arthur.cohen
2023-04-05 14:03 ` [committed 24/88] gccrs: Create and use CompilePatternLet visitor for compiling let statments arthur.cohen
2023-04-05 14:03 ` [committed 25/88] gccrs: parser: Allow parsing multiple reference types arthur.cohen
2023-04-05 14:03 ` [committed 26/88] gccrs: Move rust-buffered-queue.h to util folder #1766 arthur.cohen
2023-04-05 14:03 ` [committed 27/88] gccrs: Improve GroupedPattern lowering arthur.cohen
2023-04-05 14:03 ` [committed 28/88] gccrs: Remove HIR::GroupedPattern arthur.cohen
2023-04-05 14:03 ` [committed 29/88] gccrs: Optimize HIR::ReferencePattern arthur.cohen
2023-04-05 14:03 ` [committed 30/88] gccrs: Implement lowering ReferencePattern from AST to HIR arthur.cohen
2023-04-05 14:03 ` [committed 31/88] gccrs: parser: Improve parsing of complex generic arguments arthur.cohen
2023-04-05 14:03 ` [committed 32/88] gccrs: parser: Fix parsing of closure param list arthur.cohen
2023-04-05 14:03 ` [committed 33/88] gccrs: Add support for feature check arthur.cohen
2023-04-05 14:03 ` [committed 34/88] gccrs: Removed comment copy-pasted from gcc/tree.def arthur.cohen
2023-04-05 14:03 ` [committed 35/88] gccrs: Add another test case for passing associated type-bounds arthur.cohen
2023-04-05 14:03 ` [committed 36/88] gccrs: Move TypePredicateItem impl out of the header arthur.cohen
2023-04-05 14:03 ` [committed 37/88] gccrs: Refactor TyVar and TypeBoundPredicates arthur.cohen
2023-04-05 14:03 ` arthur.cohen [this message]
2023-04-05 14:03 ` [committed 39/88] gccrs: Refactor all substitution mapper code implementation into its own CC file arthur.cohen
2023-04-05 14:03 ` [committed 40/88] gccrs: Refactor BaseType, InferType and ErrorType impl into cc file arthur.cohen
2023-04-05 14:03 ` [committed 41/88] gccrs: Refactor PathProbe " arthur.cohen
2023-04-05 14:03 ` [committed 42/88] gccrs: Refactor PathProbeType code into CC file arthur.cohen
2023-04-05 14:03 ` [committed 43/88] gccrs: Refactor all code out of the rust-tyty.h header arthur.cohen
2023-04-05 14:03 ` [committed 44/88] gccrs: Rename rust-tyctx.cc to rust-typecheck-context.cc arthur.cohen
2023-04-05 14:03 ` [committed 45/88] gccrs: Rename header rust-hir-trait-ref.h to rust-hir-trait-reference.h arthur.cohen
2023-04-05 14:03 ` [committed 46/88] gccrs: Refactor handle_substitutions to take a reference arthur.cohen
2023-04-05 14:03 ` [committed 47/88] gccrs: Clear the substitution callbacks when copying ArgumentMappings arthur.cohen
2023-04-05 14:03 ` [committed 48/88] gccrs: Add missing param subst callback arthur.cohen
2023-04-05 14:03 ` [committed 49/88] gccrs: Remove monomorphization hack to setup possible associated types arthur.cohen
2023-04-05 14:03 ` [committed 50/88] gccrs: Refactor the type unification code arthur.cohen
2023-04-05 14:03 ` [committed 51/88] gccrs: Fix nullptr dereference arthur.cohen
2023-04-05 14:03 ` [committed 52/88] gccrs: Add missing Sized, Copy and Clone lang item mappings arthur.cohen
2023-04-05 14:03 ` [committed 53/88] gccrs: Fix higher ranked trait bounds computation of self arthur.cohen
2023-04-05 14:03 ` [committed 54/88] gccrs: Remove bad error message on checking function arguments arthur.cohen
2023-04-05 14:03 ` [committed 55/88] gccrs: Add general TypeBounds checks arthur.cohen
2023-04-05 14:03 ` [committed 56/88] gccrs: Add support for TuplePattern in let statements arthur.cohen
2023-04-05 14:03 ` [committed 57/88] gccrs: rust-item: include rust-expr.h arthur.cohen
2023-04-05 14:03 ` [committed 58/88] gccrs: parser: Expose parse_macro_invocation as public API arthur.cohen
2023-04-05 14:03 ` [committed 59/88] gccrs: expansion: Add `get_token_slice` to `MacroInvocLexer` class arthur.cohen
2023-04-05 14:03 ` [committed 60/88] gccrs: macros: Perform macro expansion in a fixed-point fashion arthur.cohen
2023-04-05 14:03 ` [committed 61/88] gccrs: expander: Add documentation for `expand_eager_invocations` arthur.cohen
2023-04-05 14:03 ` [committed 62/88] gccrs: typecheck: Refactor rust-hir-trait-reference.h arthur.cohen
2023-04-05 14:03 ` [committed 63/88] gccrs: cli: Update safety warning message arthur.cohen
2023-04-05 14:03 ` [committed 64/88] gccrs: Update copyright years arthur.cohen
2023-04-05 14:03 ` [committed 65/88] gccrs: Add feature gate for "rust-intrinsic" arthur.cohen
2023-04-05 14:03 ` [committed 66/88] gccrs: Add variadic argument type checking arthur.cohen
2023-04-05 14:03 ` [committed 67/88] gccrs: Add test arthur.cohen
2023-04-05 14:03 ` [committed 68/88] gccrs: Simplify WildcardPattern let statement handling arthur.cohen
2023-04-05 14:03 ` [committed 69/88] gccrs: lex: Prevent directories in RAIIFile arthur.cohen
2023-04-05 14:03 ` [committed 70/88] gccrs: testsuite: Add empty string macro test arthur.cohen
2023-04-05 14:03 ` [committed 71/88] gccrs: Add support for parsing empty tuple patterns arthur.cohen
2023-04-05 14:03 ` [committed 72/88] gccrs: Implemented UTF-8 checking for include_str!() arthur.cohen
2023-04-05 14:03 ` [committed 73/88] gccrs: Extract query_type from TypeCheckBase to be a simple extern arthur.cohen
2023-04-05 14:03 ` [committed 74/88] gccrs: Add new virtual function HIR::ImplItem::get_impl_item_name arthur.cohen
2023-04-05 14:03 ` [committed 75/88] gccrs: Support for Sized builtin marker trait arthur.cohen
2023-04-05 14:04 ` [committed 76/88] gccrs: Fix regression in testcase arthur.cohen
2023-04-05 14:04 ` [committed 77/88] gccrs: Add trailing newline arthur.cohen
2023-04-05 14:04 ` [committed 78/88] gccrs: builtins: Return empty list of tokens instead of nullptr arthur.cohen
2023-04-05 14:04 ` [committed 79/88] gccrs: Fix formatting arthur.cohen
2023-04-05 14:04 ` [committed 80/88] gccrs: Add AST::AltPattern class arthur.cohen
2023-04-05 14:04 ` [committed 81/88] gccrs: Fix up DejaGnu directives in 'rust/compile/issue-1830_{bytes,str}.rs' test cases [#1838] arthur.cohen
2023-04-05 14:04 ` [committed 82/88] gccrs: rename rust-hir-full-tests.cc arthur.cohen
2023-04-05 14:04 ` [committed 83/88] gccrs: add test case to show our query-type system is working arthur.cohen
2023-04-05 14:04 ` [committed 84/88] gccrs: ast: Refactor TraitItem to keep Location info arthur.cohen
2023-04-05 14:04 ` [committed 85/88] gccrs: diagnostic: Refactor Error class arthur.cohen
2023-04-05 14:04 ` [committed 86/88] gccrs: Added AST Node AST::InlineAsm arthur.cohen
2023-04-05 14:04 ` [committed 87/88] gccrs: Address unsafe with/without block handling ambiguity arthur.cohen
2023-04-05 14:04 ` [committed 88/88] gccrs: Fix issue with parsing unsafe block expression statements arthur.cohen
2023-04-06  7:59 ` Rust front-end update 2023-04-05 Thomas Schwinge
2023-04-06  9:05   ` Arthur Cohen
2023-04-11  9:09 ` Richard Biener

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230405140411.3016563-39-arthur.cohen@embecosm.com \
    --to=arthur.cohen@embecosm.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=gcc-rust@gcc.gnu.org \
    --cc=herron.philip@googlemail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).