From: Philip Herron <[email protected]>

We currently alawys resolve function body and signiture together this
seperates the two concepts so we can change query type if a fn is not
resolved to only query the signiture and not start the cascade of resolving
body calling others etc.

gcc/rust/ChangeLog:

        * typecheck/rust-hir-type-check-implitem.cc (TypeCheckImplItem::visit): 
seperate
        (TypeCheckImplItem::resolve_function_signature): likewise
        * typecheck/rust-hir-type-check-implitem.h: seperate
        * typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit): likewise
        (TypeCheckItem::resolve_function_signature): likewise
        * typecheck/rust-hir-type-check-item.h: likewise

Signed-off-by: Philip Herron <[email protected]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.


Commit on github: 
https://github.com/Rust-GCC/gccrs/commit/850672be0b013ebd85f81f419a07bb8ebd928ca0

The commit has NOT been mentioned in any issue.

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/4816

 .../typecheck/rust-hir-type-check-implitem.cc | 38 ++++++++++++++-----
 .../typecheck/rust-hir-type-check-implitem.h  |  2 +
 .../typecheck/rust-hir-type-check-item.cc     | 34 +++++++++++++----
 gcc/rust/typecheck/rust-hir-type-check-item.h |  2 +
 4 files changed, 60 insertions(+), 16 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc 
b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
index a29793c83..f8808351e 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
@@ -203,11 +203,9 @@ TypeCheckImplItem::Resolve (
   return resolver.result;
 }
 
-void
-TypeCheckImplItem::visit (HIR::Function &function)
+TyTy::FnType *
+TypeCheckImplItem::resolve_function_signature (HIR::Function &function)
 {
-  auto binder_pin = context->push_lifetime_binder ();
-
   if (function.has_generics ())
     resolve_generic_params (HIR::Item::ItemKind::Function,
                            function.get_locus (),
@@ -230,7 +228,7 @@ TypeCheckImplItem::visit (HIR::Function &function)
        {
          rust_error_at (function.get_locus (),
                         "failed to resolve return type");
-         return;
+         return nullptr;
        }
 
       ret_type = resolved->clone ();
@@ -285,7 +283,7 @@ TypeCheckImplItem::visit (HIR::Function &function)
                      {
                        rust_inform (self_param.get_locus (),
                                     "failed to resolve lifetime");
-                       return;
+                       return nullptr;
                      }
                  }
                else
@@ -310,7 +308,7 @@ TypeCheckImplItem::visit (HIR::Function &function)
                      {
                        rust_error_at (self_param.get_locus (),
                                       "failed to resolve lifetime");
-                       return;
+                       return nullptr;
                      }
                  }
                else
@@ -326,7 +324,7 @@ TypeCheckImplItem::visit (HIR::Function &function)
 
            default:
              rust_unreachable ();
-             return;
+             return nullptr;
            }
        }
 
@@ -367,8 +365,30 @@ TypeCheckImplItem::visit (HIR::Function &function)
   context->insert_type (function.get_mappings (), fnType);
   result = fnType;
 
+  return fnType;
+}
+
+void
+TypeCheckImplItem::visit (HIR::Function &function)
+{
+  auto binder_pin = context->push_lifetime_binder ();
+
+  TyTy::BaseType *resolved = nullptr;
+  TyTy::FnType *resolve_fn_type = nullptr;
+  if (context->lookup_type (function.get_mappings ().get_hirid (), &resolved))
+    {
+      if (resolved->get_kind () != TyTy::TypeKind::FNDEF)
+       return;
+      resolve_fn_type = static_cast<TyTy::FnType *> (resolved);
+      result = resolve_fn_type;
+    }
+  else
+    resolve_fn_type = resolve_function_signature (function);
+
+  if (resolve_fn_type == nullptr)
+    return;
+
   // need to get the return type from this
-  TyTy::FnType *resolve_fn_type = fnType;
   auto expected_ret_tyty = resolve_fn_type->get_return_type ();
   context->push_return_type (TypeCheckContextItem (parent, &function),
                             expected_ret_tyty);
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.h 
b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
index eb0a0f985..cba105434 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
@@ -58,6 +58,8 @@ protected:
   TypeCheckImplItem (HIR::ImplBlock &parent, TyTy::BaseType *self,
                     std::vector<TyTy::SubstitutionParamMapping> substitutions);
 
+  TyTy::FnType *resolve_function_signature (HIR::Function &function);
+
   HIR::ImplBlock &parent;
   TyTy::BaseType *self;
   std::vector<TyTy::SubstitutionParamMapping> substitutions;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc 
b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index 1b8b929bd..25fa97a36 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -794,10 +794,9 @@ TypeCheckItem::resolve_impl_item (HIR::ImplBlock 
&impl_block,
   return TypeCheckImplItem::Resolve (impl_block, item, self, substitutions);
 }
 
-void
-TypeCheckItem::visit (HIR::Function &function)
+TyTy::FnType *
+TypeCheckItem::resolve_function_signature (HIR::Function &function)
 {
-  auto lifetime_pin = context->push_clean_lifetime_resolver ();
   std::vector<TyTy::SubstitutionParamMapping> substitutions;
   if (function.has_generics ())
     resolve_generic_params (HIR::Item::ItemKind::Function,
@@ -817,7 +816,7 @@ TypeCheckItem::visit (HIR::Function &function)
     {
       auto resolved = TypeCheckType::Resolve (function.get_return_type ());
       if (resolved->get_kind () == TyTy::TypeKind::ERROR)
-       return;
+       return nullptr;
 
       ret_type = resolved->clone ();
       ret_type->set_ref (
@@ -855,8 +854,29 @@ TypeCheckItem::visit (HIR::Function &function)
 
   context->insert_type (function.get_mappings (), fn_type);
 
+  return fn_type;
+}
+
+void
+TypeCheckItem::visit (HIR::Function &function)
+{
+  auto lifetime_pin = context->push_clean_lifetime_resolver ();
+
+  TyTy::BaseType *resolved = nullptr;
+  TyTy::FnType *resolved_fn_type = nullptr;
+  if (context->lookup_type (function.get_mappings ().get_hirid (), &resolved))
+    {
+      if (resolved->get_kind () != TyTy::TypeKind::FNDEF)
+       return;
+      resolved_fn_type = static_cast<TyTy::FnType *> (resolved);
+    }
+  else
+    resolved_fn_type = resolve_function_signature (function);
+
+  if (resolved_fn_type == nullptr)
+    return;
+
   // need to get the return type from this
-  TyTy::FnType *resolved_fn_type = fn_type;
   auto expected_ret_tyty = resolved_fn_type->get_return_type ();
   context->push_return_type (TypeCheckContextItem (&function),
                             expected_ret_tyty);
@@ -866,7 +886,7 @@ TypeCheckItem::visit (HIR::Function &function)
 
   // emit check for
   // error[E0121]: the type placeholder `_` is not allowed within types on item
-  const auto placeholder = ret_type->contains_infer ();
+  const auto placeholder = expected_ret_tyty->contains_infer ();
   if (placeholder != nullptr && function.has_return_type ())
     {
       // FIXME
@@ -906,7 +926,7 @@ TypeCheckItem::visit (HIR::Function &function)
 
   context->pop_return_type ();
 
-  infered = fn_type;
+  infered = resolved_fn_type;
 }
 
 void
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.h 
b/gcc/rust/typecheck/rust-hir-type-check-item.h
index 52be8e2f6..389b0fd9a 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.h
@@ -88,6 +88,8 @@ protected:
 
   TyTy::BaseType *resolve_impl_block_self (HIR::ImplBlock &impl_block);
 
+  TyTy::FnType *resolve_function_signature (HIR::Function &function);
+
   bool validate_repr_simd (const std::vector<TyTy::StructFieldType *> &fields,
                           location_t locus);
 
-- 
2.55.0

Reply via email to