]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Fix generic argument tracking
authorPhilip Herron <herron.philip@googlemail.com>
Tue, 20 Jun 2023 15:39:25 +0000 (16:39 +0100)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 16 Jan 2024 17:46:28 +0000 (18:46 +0100)
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>
gcc/rust/typecheck/rust-hir-type-check-path.cc
gcc/rust/typecheck/rust-tyty-subst.cc
gcc/rust/typecheck/rust-tyty-subst.h

index 7de6f6627b09ebd52d000bcbcd49ca4e7c695768..1b80259e863c55e7fc248c5685a4294beb27095c 100644 (file)
@@ -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);
            }
        }
 
index 9d8164cc6760e3f027448f5b493f0e82883df08c..9c304d92933a6ef39e2ed8f5aa928a7630b1ad66 100644 (file)
@@ -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;
index d6319e50c3f8b8665e1e06ec9ed8418bfbf0a2c4..73812ffcfe8bf800aca75196ed09a6e41854e488 100644 (file)
@@ -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;
 };