[gcc r14-7682] gccrs: Fix generic argument tracking

Arthur Cohen cohenarthur@gcc.gnu.org
Tue Jan 16 17:53:21 GMT 2024


https://gcc.gnu.org/g:5189a22a14c99b9d56c4ce14d7b4d8206caf8dd2

commit r14-7682-g5189a22a14c99b9d56c4ce14d7b4d8206caf8dd2
Author: Philip Herron <herron.philip@googlemail.com>
Date:   Tue Jun 20 16:39:25 2023 +0100

    gccrs: Fix generic argument tracking
    
    When we do generic argument substitution we creating mappings of the
    HIR::GenericArgs argument to the TyTy::SubstitutionParam as a pointer. So
    for example when we have Generic Parameters <Self, T> and arguments <T, U>
    
      T0: Arguments: <Self=T, T=U>
      T1: Self -> replaced-with T
      T2: Arguments: <T=T, T=U>
      T3: T maps back to the replace Self->T
      T4: Arguments <T=T, T=T>
    
    Which is wrong but because we do a string comparison to find the argument
    mapping we cant reply on the pointer to the origin parameter mapping as
    the parameter will be updated resulting in bad mappings.
    
    This patch changes the Argument mappings to track the _original_ parameter
    type so that lookup's for the mappings use this symbol instead not the
    updated ones during substitution.
    
    Addresses #1893
    
    gcc/rust/ChangeLog:
    
            * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::resolve_segments):
            simplify lookup of the respective predicate
            * typecheck/rust-tyty-subst.cc (SubstitutionArg::SubstitutionArg): track original parameter
            (SubstitutionArg::operator=): update copy ctor
            (SubstitutionArg::get_param_ty): use original param
            (SubstitutionArg::as_string): update as_string
            * typecheck/rust-tyty-subst.h: add new private field
    
    Signed-off-by: Philip Herron <herron.philip@googlemail.com>

Diff:
---
 gcc/rust/typecheck/rust-hir-type-check-path.cc | 26 +++++++++-----------------
 gcc/rust/typecheck/rust-tyty-subst.cc          | 22 ++++++++++++++++------
 gcc/rust/typecheck/rust-tyty-subst.h           |  3 +++
 3 files changed, 28 insertions(+), 23 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index 7de6f6627b0..1b80259e863 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -431,23 +431,15 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
 	      // we need to setup with apropriate bounds
 	      HIR::TypePath &bound_path
 		= *associated->get_impl_block ()->get_trait_ref ().get ();
-
-	      // generate an implicit HIR Type we can apply to the predicate
-	      HirId implicit_id = mappings->get_next_hir_id ();
-	      context->insert_implicit_type (implicit_id, impl_block_ty);
-
-	      Analysis::NodeMapping mappings (expr_mappings.get_crate_num (),
-					      expr_mappings.get_nodeid (),
-					      implicit_id,
-					      expr_mappings.get_local_defid ());
-	      HIR::TypePath *implicit_self_bound
-		= new HIR::TypePath (mappings, {},
-				     Linemap::predeclared_location (), false);
-
-	      TyTy::TypeBoundPredicate predicate
-		= get_predicate_from_bound (bound_path, implicit_self_bound);
-	      impl_block_ty
-		= associated->setup_associated_types (prev_segment, predicate);
+	      const auto &trait_ref = *TraitResolver::Resolve (bound_path);
+	      rust_assert (!trait_ref.is_error ());
+
+	      const auto &predicate
+		= impl_block_ty->lookup_predicate (trait_ref.get_defid ());
+	      if (!predicate.is_error ())
+		impl_block_ty
+		  = associated->setup_associated_types (prev_segment,
+							predicate);
 	    }
 	}
 
diff --git a/gcc/rust/typecheck/rust-tyty-subst.cc b/gcc/rust/typecheck/rust-tyty-subst.cc
index 9d8164cc676..9c304d92933 100644
--- a/gcc/rust/typecheck/rust-tyty-subst.cc
+++ b/gcc/rust/typecheck/rust-tyty-subst.cc
@@ -168,10 +168,14 @@ SubstitutionParamMapping::override_context ()
 SubstitutionArg::SubstitutionArg (const SubstitutionParamMapping *param,
 				  BaseType *argument)
   : param (param), argument (argument)
-{}
+{
+  if (param != nullptr)
+    original_param = param->get_param_ty ();
+}
 
 SubstitutionArg::SubstitutionArg (const SubstitutionArg &other)
-  : param (other.param), argument (other.argument)
+  : param (other.param), original_param (other.original_param),
+    argument (other.argument)
 {}
 
 SubstitutionArg &
@@ -179,6 +183,8 @@ SubstitutionArg::operator= (const SubstitutionArg &other)
 {
   param = other.param;
   argument = other.argument;
+  original_param = other.original_param;
+
   return *this;
 }
 
@@ -200,6 +206,12 @@ SubstitutionArg::get_param_mapping () const
   return param;
 }
 
+const ParamType *
+SubstitutionArg::get_param_ty () const
+{
+  return original_param;
+}
+
 SubstitutionArg
 SubstitutionArg::error ()
 {
@@ -227,7 +239,7 @@ SubstitutionArg::is_conrete () const
 std::string
 SubstitutionArg::as_string () const
 {
-  return param->as_string ()
+  return original_param->as_string ()
 	 + (argument != nullptr ? ":" + argument->as_string () : "");
 }
 
@@ -289,9 +301,7 @@ SubstitutionArgumentMappings::get_argument_for_symbol (
 {
   for (auto &mapping : mappings)
     {
-      const SubstitutionParamMapping *param = mapping.get_param_mapping ();
-      const ParamType *p = param->get_param_ty ();
-
+      const ParamType *p = mapping.get_param_ty ();
       if (p->get_symbol ().compare (param_to_find->get_symbol ()) == 0)
 	{
 	  *argument = mapping;
diff --git a/gcc/rust/typecheck/rust-tyty-subst.h b/gcc/rust/typecheck/rust-tyty-subst.h
index d6319e50c3f..73812ffcfe8 100644
--- a/gcc/rust/typecheck/rust-tyty-subst.h
+++ b/gcc/rust/typecheck/rust-tyty-subst.h
@@ -87,6 +87,8 @@ public:
 
   const SubstitutionParamMapping *get_param_mapping () const;
 
+  const ParamType *get_param_ty () const;
+
   static SubstitutionArg error ();
 
   bool is_error () const;
@@ -97,6 +99,7 @@ public:
 
 private:
   const SubstitutionParamMapping *param;
+  const ParamType *original_param;
   BaseType *argument;
 };


More information about the Gcc-cvs mailing list