]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Apply generic arguments to the respective trait bounds
authorPhilip Herron <herron.philip@googlemail.com>
Tue, 20 Jun 2023 18:41:42 +0000 (19:41 +0100)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 16 Jan 2024 17:46:28 +0000 (18:46 +0100)
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>
gcc/rust/typecheck/rust-hir-type-check-item.cc
gcc/rust/typecheck/rust-hir-type-check-item.h
gcc/rust/typecheck/rust-hir-type-check-path.cc
gcc/testsuite/rust/compile/issue-1893.rs

index 8a06e6dbd189f2eb68cc95cba128a4a5d1a99b01..a34ae0766d6e23c2a4d7a7a0d9940643554ea0ab 100644 (file)
@@ -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
index fc49dc69b05cee7e35ad82b9ee9fe044439b52ed..bbe3a114bc61437192317007ffae22b653a2e67b 100644 (file)
@@ -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;
index 1b80259e863c55e7fc248c5685a4294beb27095c..54ca28ff4d6e4028f593b84ae65f2ed3e143f074 100644 (file)
@@ -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),
index 8d32e0d37c8dc20ef327e6a19d4a21c3f6a76da5..6be1d6d6f29474bbfe5cb6ef618bfc6bdc552e9d 100644 (file)
@@ -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>;
 }