[gcc r14-7683] gccrs: Apply generic arguments to the respective trait bounds

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


https://gcc.gnu.org/g:97bc533c525629410ffc520170c950af69490afd

commit r14-7683-g97bc533c525629410ffc520170c950af69490afd
Author: Philip Herron <herron.philip@googlemail.com>
Date:   Tue Jun 20 19:41:42 2023 +0100

    gccrs: Apply generic arguments to the respective trait bounds
    
    When we have an impl block for a generic type such as T which is a generic
    type which does not 'bind' generic arguments, which means its not a type
    such as an ADT or Fn which holds generic parameter mappings we need to
    ensure inference variables are applied to the segment type apropriately so
    that inference variables unified correctly and the higher ranked trait
    bounds are as well.
    
    Fixes: #1893
    
    gcc/rust/ChangeLog:
    
            * typecheck/rust-hir-type-check-item.cc (TypeCheckItem::ResolveImplBlockSelfWithInference):
            arguments mappings as an out parameter and apply them to the bounds
            * typecheck/rust-hir-type-check-item.h: update the prototype
            * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::resolve_segments):
            apply the arguments to the segment type
    
    gcc/testsuite/ChangeLog:
    
            * rust/compile/issue-1893.rs: fully compile the test case
    
    Signed-off-by: Philip Herron <herron.philip@googlemail.com>

Diff:
---
 gcc/rust/typecheck/rust-hir-type-check-item.cc | 21 ++++++++++++++++-----
 gcc/rust/typecheck/rust-hir-type-check-item.h  |  5 +++--
 gcc/rust/typecheck/rust-hir-type-check-path.cc |  9 ++++++++-
 gcc/testsuite/rust/compile/issue-1893.rs       |  3 ---
 4 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index 8a06e6dbd18..a34ae0766d6 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -74,8 +74,9 @@ TypeCheckItem::ResolveImplBlockSelf (HIR::ImplBlock &impl_block)
 }
 
 TyTy::BaseType *
-TypeCheckItem::ResolveImplBlockSelfWithInference (HIR::ImplBlock &impl,
-						  Location locus)
+TypeCheckItem::ResolveImplBlockSelfWithInference (
+  HIR::ImplBlock &impl, Location locus,
+  TyTy::SubstitutionArgumentMappings *infer_arguments)
 {
   TypeCheckItem resolver;
 
@@ -112,10 +113,20 @@ TypeCheckItem::ResolveImplBlockSelfWithInference (HIR::ImplBlock &impl,
     }
 
   // create argument mappings
-  TyTy::SubstitutionArgumentMappings infer_arguments (std::move (args), {},
-						      locus);
+  *infer_arguments
+    = TyTy::SubstitutionArgumentMappings (std::move (args), {}, locus);
 
-  return SubstMapperInternal::Resolve (self, infer_arguments);
+  TyTy::BaseType *infer = SubstMapperInternal::Resolve (self, *infer_arguments);
+
+  // we only need to apply to the bounds manually on types which dont bind
+  // generics
+  if (!infer->has_subsititions_defined ())
+    {
+      for (auto &bound : infer->get_specified_bounds ())
+	bound.handle_substitions (*infer_arguments);
+    }
+
+  return infer;
 }
 
 void
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.h b/gcc/rust/typecheck/rust-hir-type-check-item.h
index fc49dc69b05..bbe3a114bc6 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.h
@@ -35,8 +35,9 @@ public:
 
   static TyTy::BaseType *ResolveImplBlockSelf (HIR::ImplBlock &impl_block);
 
-  static TyTy::BaseType *
-  ResolveImplBlockSelfWithInference (HIR::ImplBlock &impl, Location locus);
+  static TyTy::BaseType *ResolveImplBlockSelfWithInference (
+    HIR::ImplBlock &impl, Location locus,
+    TyTy::SubstitutionArgumentMappings *infer_arguments);
 
   void visit (HIR::Module &module) override;
   void visit (HIR::Function &function) override;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index 1b80259e863..54ca28ff4d6 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -414,9 +414,16 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
 	  bool found_impl_trait
 	    = context->lookup_associated_trait_impl (impl_block_id,
 						     &associated);
+
+	  auto mappings = TyTy::SubstitutionArgumentMappings::error ();
 	  TyTy::BaseType *impl_block_ty
 	    = TypeCheckItem::ResolveImplBlockSelfWithInference (
-	      *associated_impl_block, seg.get_locus ());
+	      *associated_impl_block, seg.get_locus (), &mappings);
+
+	  // we need to apply the arguments to the segment type so they get
+	  // unified properly
+	  if (!mappings.is_error ())
+	    tyseg = SubstMapperInternal::Resolve (tyseg, mappings);
 
 	  prev_segment = unify_site (seg.get_mappings ().get_hirid (),
 				     TyTy::TyWithLocation (prev_segment),
diff --git a/gcc/testsuite/rust/compile/issue-1893.rs b/gcc/testsuite/rust/compile/issue-1893.rs
index 8d32e0d37c8..6be1d6d6f29 100644
--- a/gcc/testsuite/rust/compile/issue-1893.rs
+++ b/gcc/testsuite/rust/compile/issue-1893.rs
@@ -1,4 +1,3 @@
-// { dg-additional-options "-frust-compile-until=nameresolution" }
 pub enum Option<T> {
     None,
     Some(T),
@@ -10,10 +9,8 @@ pub enum Result<T, E> {
 }
 
 pub trait TryFrom<T> {
-    /// The type returned in the event of a conversion error.
     type Error;
 
-    /// Performs the conversion.
     fn try_from(value: T) -> Result<Self, Self::Error>;
 }


More information about the Gcc-cvs mailing list