[gcc r14-7681] gccrs: add new method to infer impl block type

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


https://gcc.gnu.org/g:4476c9a8e386575c272c96a7e9383b011f273d77

commit r14-7681-g4476c9a8e386575c272c96a7e9383b011f273d77
Author: Philip Herron <herron.philip@googlemail.com>
Date:   Tue Jun 20 12:21:02 2023 +0100

    gccrs: add new method to infer impl block type
    
    When we resolve a path segment the associated impl Self may not be a type
    which 'binds' generic types. Which would be any type which does not inherit
    SubstitionRef base class. There is a case where an impl block for generic
    type T has bound generics on the trait bound of the trait impl block this
    allows us to infer the T for this case.
    
    Addresses #1893
    
    gcc/rust/ChangeLog:
    
            * typecheck/rust-hir-type-check-item.cc (TypeCheckItem::ResolveImplBlockSelfWithInference):
            New helper utility to infer non concrete types and handle the case where its not a
            binding generic type (which inherits SubstitutionRef)
            * typecheck/rust-hir-type-check-item.h: new helper prototype
            * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::resolve_segments): use this helper
    
    Signed-off-by: Philip Herron <herron.philip@googlemail.com>

Diff:
---
 gcc/rust/typecheck/rust-hir-type-check-item.cc | 45 ++++++++++++++++++++++++++
 gcc/rust/typecheck/rust-hir-type-check-item.h  |  3 ++
 gcc/rust/typecheck/rust-hir-type-check-path.cc |  7 ++--
 3 files changed, 50 insertions(+), 5 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index 6d6ab63e85f..8a06e6dbd18 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -73,6 +73,51 @@ TypeCheckItem::ResolveImplBlockSelf (HIR::ImplBlock &impl_block)
   return resolver.resolve_impl_block_self (impl_block);
 }
 
+TyTy::BaseType *
+TypeCheckItem::ResolveImplBlockSelfWithInference (HIR::ImplBlock &impl,
+						  Location locus)
+{
+  TypeCheckItem resolver;
+
+  bool failed_flag = false;
+  std::vector<TyTy::SubstitutionParamMapping> substitutions
+    = resolver.resolve_impl_block_substitutions (impl, failed_flag);
+  if (failed_flag)
+    {
+      return new TyTy::ErrorType (impl.get_mappings ().get_hirid ());
+    }
+
+  // now that we have the param mappings we need to query the self type
+  TyTy::BaseType *self = resolver.resolve_impl_block_self (impl);
+
+  // nothing to do
+  if (substitutions.empty () || self->is_concrete ())
+    return self;
+
+  // generate inference variables for the subst-param-mappings
+  std::vector<TyTy::SubstitutionArg> args;
+  for (auto &p : substitutions)
+    {
+      if (p.needs_substitution ())
+	{
+	  TyTy::TyVar infer_var = TyTy::TyVar::get_implicit_infer_var (locus);
+	  args.push_back (TyTy::SubstitutionArg (&p, infer_var.get_tyty ()));
+	}
+      else
+	{
+	  TyTy::ParamType *param = p.get_param_ty ();
+	  TyTy::BaseType *resolved = param->destructure ();
+	  args.push_back (TyTy::SubstitutionArg (&p, resolved));
+	}
+    }
+
+  // create argument mappings
+  TyTy::SubstitutionArgumentMappings infer_arguments (std::move (args), {},
+						      locus);
+
+  return SubstMapperInternal::Resolve (self, infer_arguments);
+}
+
 void
 TypeCheckItem::visit (HIR::TypeAlias &alias)
 {
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.h b/gcc/rust/typecheck/rust-hir-type-check-item.h
index 432b29271a5..fc49dc69b05 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.h
@@ -35,6 +35,9 @@ public:
 
   static TyTy::BaseType *ResolveImplBlockSelf (HIR::ImplBlock &impl_block);
 
+  static TyTy::BaseType *
+  ResolveImplBlockSelfWithInference (HIR::ImplBlock &impl, Location locus);
+
   void visit (HIR::Module &module) override;
   void visit (HIR::Function &function) override;
   void visit (HIR::TypeAlias &alias) override;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index 4bac75a63d9..7de6f6627b0 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -415,11 +415,8 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
 	    = context->lookup_associated_trait_impl (impl_block_id,
 						     &associated);
 	  TyTy::BaseType *impl_block_ty
-	    = TypeCheckItem::ResolveImplBlockSelf (*associated_impl_block);
-
-	  if (impl_block_ty->needs_generic_substitutions ())
-	    impl_block_ty
-	      = SubstMapper::InferSubst (impl_block_ty, seg.get_locus ());
+	    = TypeCheckItem::ResolveImplBlockSelfWithInference (
+	      *associated_impl_block, seg.get_locus ());
 
 	  prev_segment = unify_site (seg.get_mappings ().get_hirid (),
 				     TyTy::TyWithLocation (prev_segment),


More information about the Gcc-cvs mailing list