public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] Complete refactor of generic traits handling
@ 2022-06-08 12:39 Thomas Schwinge
  0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-06-08 12:39 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:be158fc97f7f4d43d60797f2af27c86753b0ffb5

commit be158fc97f7f4d43d60797f2af27c86753b0ffb5
Author: Philip Herron <philip.herron@embecosm.com>
Date:   Thu Apr 28 13:09:15 2022 +0100

    Complete refactor of generic traits handling
    
    From PR #1086 I introduced a new setup_associated_types2 interface which
    is used to ensure we handle the complex associated types in libcore slices
    but this interface was inconsistant as well as the get_projected_type.
    
    This path refactors the code base to get rid of the old
    setup_associated_types interface in favour of this new one. It also removes
    the get_projected_type interface which was not going to work either.
    
    Fixes #1105

Diff:
---
 gcc/rust/backend/rust-compile-implitem.cc      |  1 +
 gcc/rust/backend/rust-compile-item.cc          |  1 +
 gcc/rust/backend/rust-compile-resolve-path.cc  | 15 ------
 gcc/rust/typecheck/rust-hir-path-probe.h       | 12 -----
 gcc/rust/typecheck/rust-hir-trait-ref.h        | 11 +---
 gcc/rust/typecheck/rust-hir-trait-resolve.cc   | 64 +----------------------
 gcc/rust/typecheck/rust-hir-type-check-path.cc | 71 +++++++++++---------------
 gcc/rust/typecheck/rust-hir-type-check-type.cc | 67 ++++++++----------------
 gcc/rust/typecheck/rust-tyty.cc                | 22 ++++----
 9 files changed, 67 insertions(+), 197 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-implitem.cc b/gcc/rust/backend/rust-compile-implitem.cc
index 7cc214ce249..9dc6d14d629 100644
--- a/gcc/rust/backend/rust-compile-implitem.cc
+++ b/gcc/rust/backend/rust-compile-implitem.cc
@@ -52,6 +52,7 @@ CompileTraitItem::visit (HIR::TraitItemFunc &func)
 
   rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
   TyTy::FnType *fntype = static_cast<TyTy::FnType *> (concrete);
+  fntype->monomorphize ();
 
   // items can be forward compiled which means we may not need to invoke this
   // code. We might also have already compiled this generic function as well.
diff --git a/gcc/rust/backend/rust-compile-item.cc b/gcc/rust/backend/rust-compile-item.cc
index 80b7cebfb5f..969c852d516 100644
--- a/gcc/rust/backend/rust-compile-item.cc
+++ b/gcc/rust/backend/rust-compile-item.cc
@@ -127,6 +127,7 @@ CompileItem::visit (HIR::Function &function)
 	{
 	  rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
 	  fntype = static_cast<TyTy::FnType *> (concrete);
+	  fntype->monomorphize ();
 	}
     }
 
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc
index 2ad672d0b4c..55a2fffe9dd 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -251,21 +251,6 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup,
 	      rust_assert (ok);				    // found
 	      rust_assert (trait_item_ref->is_optional ()); // has definition
 
-	      Analysis::NodeMapping trait_mappings
-		= trait_item_ref->get_parent_trait_mappings ();
-
-	      HirId associated_impl_id;
-	      ok = ctx->get_tyctx ()->lookup_associated_impl_mapping_for_self (
-		trait_mappings.get_hirid (), receiver, &associated_impl_id);
-	      rust_assert (ok);
-
-	      Resolver::AssociatedImplTrait *associated = nullptr;
-	      bool found_associated_trait_impl
-		= ctx->get_tyctx ()->lookup_associated_trait_impl (
-		  associated_impl_id, &associated);
-	      rust_assert (found_associated_trait_impl);
-	      associated->setup_associated_types ();
-
 	      return CompileTraitItem::Compile (
 		trait_item_ref->get_hir_trait_item (), ctx, lookup, true,
 		expr_locus);
diff --git a/gcc/rust/typecheck/rust-hir-path-probe.h b/gcc/rust/typecheck/rust-hir-path-probe.h
index fda505aa84e..348b9f775e8 100644
--- a/gcc/rust/typecheck/rust-hir-path-probe.h
+++ b/gcc/rust/typecheck/rust-hir-path-probe.h
@@ -326,18 +326,6 @@ protected:
       }
 
     TyTy::BaseType *trait_item_tyty = trait_item_ref->get_tyty ();
-    if (impl != nullptr && !is_reciever_generic ())
-
-      {
-	HirId impl_block_id = impl->get_mappings ().get_hirid ();
-	AssociatedImplTrait *lookup_associated = nullptr;
-	bool found_impl_trait
-	  = context->lookup_associated_trait_impl (impl_block_id,
-						   &lookup_associated);
-	// see testsuite/rust/compile/torture/traits10.rs this can be false
-	if (found_impl_trait)
-	  lookup_associated->setup_associated_types ();
-      }
 
     // we can substitute the Self with the receiver here
     if (trait_item_tyty->get_kind () == TyTy::TypeKind::FNDEF)
diff --git a/gcc/rust/typecheck/rust-hir-trait-ref.h b/gcc/rust/typecheck/rust-hir-trait-ref.h
index a12736f93f3..6eec461e8a5 100644
--- a/gcc/rust/typecheck/rust-hir-trait-ref.h
+++ b/gcc/rust/typecheck/rust-hir-trait-ref.h
@@ -454,18 +454,11 @@ public:
 
   TyTy::BaseType *get_self () { return self; }
 
-  void setup_associated_types ();
-
-  void setup_associated_types2 (const TyTy::BaseType *self,
-				const TyTy::TypeBoundPredicate &bound);
+  void setup_associated_types (const TyTy::BaseType *self,
+			       const TyTy::TypeBoundPredicate &bound);
 
   void reset_associated_types ();
 
-  TyTy::BaseType *get_projected_type (const TraitItemReference *trait_item_ref,
-				      TyTy::BaseType *reciever, HirId ref,
-				      HIR::GenericArgs &trait_generics,
-				      Location expr_locus);
-
 private:
   TraitReference *trait;
   HIR::ImplBlock *impl;
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index 5681ebdd821..e7fe0e0bb90 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -154,29 +154,7 @@ TraitItemReference::associated_type_reset () const
 }
 
 void
-AssociatedImplTrait::setup_associated_types ()
-{
-  ImplTypeIterator iter (*impl, [&] (HIR::TypeAlias &type) {
-    TraitItemReference *resolved_trait_item = nullptr;
-    bool ok = trait->lookup_trait_item (type.get_new_type_name (),
-					&resolved_trait_item);
-    if (!ok)
-      return;
-    if (resolved_trait_item->get_trait_item_type ()
-	!= TraitItemReference::TraitItemType::TYPE)
-      return;
-
-    TyTy::BaseType *lookup;
-    if (!context->lookup_type (type.get_mappings ().get_hirid (), &lookup))
-      return;
-
-    resolved_trait_item->associated_type_set (lookup);
-  });
-  iter.go ();
-}
-
-void
-AssociatedImplTrait::setup_associated_types2 (
+AssociatedImplTrait::setup_associated_types (
   const TyTy::BaseType *self, const TyTy::TypeBoundPredicate &bound)
 {
   // compute the constrained impl block generic arguments based on self and the
@@ -390,46 +368,6 @@ TraitItemReference::is_object_safe () const
   return false;
 }
 
-TyTy::BaseType *
-AssociatedImplTrait::get_projected_type (
-  const TraitItemReference *trait_item_ref, TyTy::BaseType *receiver, HirId ref,
-  HIR::GenericArgs &trait_generics, Location expr_locus)
-{
-  TyTy::BaseType *trait_item_tyty = trait_item_ref->get_tyty ()->clone ();
-
-  // we can substitute the Self with the receiver here
-  if (trait_item_tyty->get_kind () == TyTy::TypeKind::FNDEF)
-    {
-      TyTy::FnType *fn = static_cast<TyTy::FnType *> (trait_item_tyty);
-      TyTy::SubstitutionParamMapping *param = nullptr;
-      for (auto &param_mapping : fn->get_substs ())
-	{
-	  const HIR::TypeParam &type_param = param_mapping.get_generic_param ();
-	  if (type_param.get_type_representation ().compare ("Self") == 0)
-	    {
-	      param = &param_mapping;
-	      break;
-	    }
-	}
-      rust_assert (param != nullptr);
-
-      std::vector<TyTy::SubstitutionArg> mappings;
-      mappings.push_back (TyTy::SubstitutionArg (param, receiver->clone ()));
-
-      TyTy::SubstitutionArgumentMappings args (std::move (mappings),
-					       expr_locus);
-      trait_item_tyty = SubstMapperInternal::Resolve (trait_item_tyty, args);
-    }
-
-  if (!trait_generics.is_empty ())
-    {
-      trait_item_tyty
-	= SubstMapper::Resolve (trait_item_tyty, expr_locus, &trait_generics);
-    }
-
-  return trait_item_tyty;
-}
-
 // rust-hir-path-probe.h
 
 void
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index 9960e76dccb..3823c570d25 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -67,41 +67,41 @@ TypeCheckExpr::visit (HIR::QualifiedPathInExpression &expr)
   // inherit the bound
   root->inherit_bounds ({specified_bound});
 
-  // we need resolve to the impl block
-  NodeId impl_resolved_id = UNKNOWN_NODEID;
-  bool ok = resolver->lookup_resolved_name (
-    qual_path_type.get_mappings ().get_nodeid (), &impl_resolved_id);
-  rust_assert (ok);
-
-  HirId impl_block_id;
-  ok = mappings->lookup_node_to_hir (expr.get_mappings ().get_crate_num (),
-				     impl_resolved_id, &impl_block_id);
-  rust_assert (ok);
-
-  AssociatedImplTrait *lookup_associated = nullptr;
-  bool found_impl_trait
-    = context->lookup_associated_trait_impl (impl_block_id, &lookup_associated);
-  rust_assert (found_impl_trait);
-
+  // lookup the associated item from the specified bound
   HIR::PathExprSegment &item_seg = expr.get_segments ().at (0);
-
-  const TraitItemReference *trait_item_ref = nullptr;
-  ok = trait_ref->lookup_trait_item (item_seg.get_segment ().as_string (),
-				     &trait_item_ref);
-  if (!ok)
+  HIR::PathIdentSegment item_seg_identifier = item_seg.get_segment ();
+  TyTy::TypeBoundPredicateItem item
+    = specified_bound.lookup_associated_item (item_seg_identifier.as_string ());
+  if (item.is_error ())
     {
       rust_error_at (item_seg.get_locus (), "unknown associated item");
       return;
     }
 
-  HIR::GenericArgs trait_generics = qual_path_type.trait_has_generic_args ()
-				      ? qual_path_type.get_trait_generic_args ()
-				      : HIR::GenericArgs::create_empty ();
+  // infer the root type
+  infered = item.get_tyty_for_receiver (root);
 
-  lookup_associated->setup_associated_types ();
-  infered = lookup_associated->get_projected_type (
-    trait_item_ref, root, item_seg.get_mappings ().get_hirid (), trait_generics,
-    item_seg.get_locus ());
+  // we need resolve to the impl block
+  NodeId impl_resolved_id = UNKNOWN_NODEID;
+  bool have_associated_impl = resolver->lookup_resolved_name (
+    qual_path_type.get_mappings ().get_nodeid (), &impl_resolved_id);
+  AssociatedImplTrait *lookup_associated = nullptr;
+  if (have_associated_impl)
+    {
+      HirId impl_block_id;
+      bool ok
+	= mappings->lookup_node_to_hir (expr.get_mappings ().get_crate_num (),
+					impl_resolved_id, &impl_block_id);
+      rust_assert (ok);
+
+      bool found_impl_trait
+	= context->lookup_associated_trait_impl (impl_block_id,
+						 &lookup_associated);
+      if (found_impl_trait)
+	{
+	  lookup_associated->setup_associated_types (root, specified_bound);
+	}
+    }
 
   // turbo-fish segment path::<ty>
   if (item_seg.has_generic_args ())
@@ -119,6 +119,7 @@ TypeCheckExpr::visit (HIR::QualifiedPathInExpression &expr)
     }
 
   // continue on as a path-in-expression
+  const TraitItemReference *trait_item_ref = item.get_raw_item ();
   NodeId root_resolved_node_id = trait_item_ref->get_mappings ().get_nodeid ();
   bool fully_resolved = expr.get_segments ().size () <= 1;
 
@@ -348,20 +349,6 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
 	  HIR::ImplBlock *impl = candidate.item.trait.impl;
 	  if (impl != nullptr)
 	    {
-	      AssociatedImplTrait *lookup_associated = nullptr;
-	      bool found_impl_trait = context->lookup_associated_trait_impl (
-		impl->get_mappings ().get_hirid (), &lookup_associated);
-
-	      // setup associated mappings if possible we might be resolving a
-	      // path within a default implementation of a trait function
-	      // see: testsuite/rust/compile/torture/traits16.rs
-	      if (found_impl_trait)
-		lookup_associated->setup_associated_types ();
-
-	      // we need a new ty_ref_id for this trait item
-	      tyseg = tyseg->clone ();
-	      tyseg->set_ty_ref (mappings->get_next_hir_id ());
-
 	      // get the associated impl block
 	      associated_impl_block = impl;
 	    }
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index 914bebbecf8..bd40344aa6c 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -142,31 +142,35 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
       return;
     }
 
+  // get the predicate for the bound
+  auto specified_bound
+    = get_predicate_from_bound (*qual_path_type.get_trait ().get ());
+  if (specified_bound.is_error ())
+    return;
+
+  // inherit the bound
+  root->inherit_bounds ({specified_bound});
+
+  // lookup the associated item from the specified bound
   std::unique_ptr<HIR::TypePathSegment> &item_seg
     = path.get_associated_segment ();
-  const TraitItemReference *trait_item_ref = nullptr;
-  bool ok
-    = trait_ref->lookup_trait_item (item_seg->get_ident_segment ().as_string (),
-				    &trait_item_ref);
-  if (!ok)
+  HIR::PathIdentSegment item_seg_identifier = item_seg->get_ident_segment ();
+  TyTy::TypeBoundPredicateItem item
+    = specified_bound.lookup_associated_item (item_seg_identifier.as_string ());
+  if (item.is_error ())
     {
       rust_error_at (item_seg->get_locus (), "unknown associated item");
       return;
     }
 
-  // this will be the placeholder from the trait but we may be able to project
-  // it based on the impl block
-  translated = trait_item_ref->get_tyty ();
-
-  // this is the associated generics we need to potentially apply
-  HIR::GenericArgs trait_generics = qual_path_type.trait_has_generic_args ()
-				      ? qual_path_type.get_trait_generic_args ()
-				      : HIR::GenericArgs::create_empty ();
+  // infer the root type
+  translated = item.get_tyty_for_receiver (root);
 
   // we need resolve to the impl block
   NodeId impl_resolved_id = UNKNOWN_NODEID;
   bool have_associated_impl = resolver->lookup_resolved_name (
     qual_path_type.get_mappings ().get_nodeid (), &impl_resolved_id);
+  AssociatedImplTrait *lookup_associated = nullptr;
   if (have_associated_impl)
     {
       HirId impl_block_id;
@@ -175,30 +179,16 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
 					impl_resolved_id, &impl_block_id);
       rust_assert (ok);
 
-      AssociatedImplTrait *lookup_associated = nullptr;
       bool found_impl_trait
 	= context->lookup_associated_trait_impl (impl_block_id,
 						 &lookup_associated);
-      rust_assert (found_impl_trait);
-
-      // project
-      lookup_associated->setup_associated_types ();
-      translated = lookup_associated->get_projected_type (
-	trait_item_ref, root, item_seg->get_mappings ().get_hirid (),
-	trait_generics, item_seg->get_locus ());
-    }
-
-  if (translated->get_kind () == TyTy::TypeKind::PLACEHOLDER)
-    {
-      // lets grab the actual projection type
-      TyTy::PlaceholderType *p
-	= static_cast<TyTy::PlaceholderType *> (translated);
-      if (p->can_resolve ())
+      if (found_impl_trait)
 	{
-	  translated = p->resolve ();
+	  lookup_associated->setup_associated_types (root, specified_bound);
 	}
     }
 
+  // turbo-fish segment path::<ty>
   if (item_seg->get_type () == HIR::TypePathSegment::SegmentType::GENERIC)
     {
       HIR::TypePathSegmentGeneric &generic_seg
@@ -222,6 +212,7 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
     }
 
   // continue on as a path-in-expression
+  const TraitItemReference *trait_item_ref = item.get_raw_item ();
   NodeId root_resolved_node_id = trait_item_ref->get_mappings ().get_nodeid ();
   bool fully_resolved = path.get_segments ().empty ();
   if (fully_resolved)
@@ -448,22 +439,6 @@ TypeCheckType::resolve_segments (
 	{
 	  resolved_node_id
 	    = candidate.item.trait.item_ref->get_mappings ().get_nodeid ();
-
-	  // lookup the associated-impl-trait
-	  HIR::ImplBlock *impl = candidate.item.trait.impl;
-	  if (impl != nullptr && !reciever_is_generic)
-	    {
-	      AssociatedImplTrait *lookup_associated = nullptr;
-	      bool found_impl_trait = context->lookup_associated_trait_impl (
-		impl->get_mappings ().get_hirid (), &lookup_associated);
-	      rust_assert (found_impl_trait);
-
-	      lookup_associated->setup_associated_types ();
-
-	      // we need a new ty_ref_id for this trait item
-	      tyseg = tyseg->clone ();
-	      tyseg->set_ty_ref (mappings->get_next_hir_id ());
-	    }
 	}
 
       if (seg->is_generic_segment ())
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 0673d209f0e..7302b069923 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -826,22 +826,23 @@ SubstitutionRef::monomorphize ()
 	      bool found_impl_trait
 		= context->lookup_associated_trait_impl (impl_block_id,
 							 &associated);
-	      rust_assert (found_impl_trait);
-
-	      bool found_trait
-		= specified_bound_ref->is_equal (*bound_trait_ref);
-	      bool found_self
-		= associated->get_self ()->can_eq (binding, false);
-	      if (found_trait && found_self)
+	      if (found_impl_trait)
 		{
-		  associated_impl_trait = associated;
-		  break;
+		  bool found_trait
+		    = specified_bound_ref->is_equal (*bound_trait_ref);
+		  bool found_self
+		    = associated->get_self ()->can_eq (binding, false);
+		  if (found_trait && found_self)
+		    {
+		      associated_impl_trait = associated;
+		      break;
+		    }
 		}
 	    }
 
 	  if (associated_impl_trait != nullptr)
 	    {
-	      associated_impl_trait->setup_associated_types2 (binding, bound);
+	      associated_impl_trait->setup_associated_types (binding, bound);
 	    }
 	}
     }
@@ -2974,6 +2975,7 @@ TypeCheckCallExpr::visit (ADTType &type)
 void
 TypeCheckCallExpr::visit (FnType &type)
 {
+  type.monomorphize ();
   if (call.num_params () != type.num_params ())
     {
       if (type.is_varadic ())


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-06-08 12:39 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-08 12:39 [gcc/devel/rust/master] Complete refactor of generic traits handling Thomas Schwinge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).