]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: track abi and unsafety on fnptrs for proper type checking
authorPhilip Herron <herron.philip@googlemail.com>
Wed, 3 Sep 2025 19:50:59 +0000 (20:50 +0100)
committerArthur Cohen <arthur.cohen@embecosm.com>
Thu, 30 Oct 2025 19:59:11 +0000 (20:59 +0100)
We need to distinguish between abi's and unsafety on fnptrs. There is
a commented out check because there is a regression in:

  rust/compile/try-catch-unwind-{new/old}.rs

But i think this is because the test case should be taking an FnOnce
from reading std::panic in rust 1.49. Where as we are passing an fnptr
which is probably because we didnt support fnonce at all then.

Addresses Rust-GCC/gccrs#4090

gcc/rust/ChangeLog:

* hir/tree/rust-hir-item.h: add unsafe helper
* typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): pass in abi and unsafe
* typecheck/rust-tyty.cc (BaseType::monomorphized_clone): likewise
(FnPtr::as_string): emit more info
(FnPtr::clone): update ctor call
* typecheck/rust-tyty.h: new ctor params
* typecheck/rust-unify.cc (UnifyRules::expect_fnptr): check abi and unsafe

Signed-off-by: Philip Herron <herron.philip@googlemail.com>
gcc/rust/hir/tree/rust-hir-item.h
gcc/rust/typecheck/rust-hir-type-check-type.cc
gcc/rust/typecheck/rust-tyty.cc
gcc/rust/typecheck/rust-tyty.h
gcc/rust/typecheck/rust-unify.cc

index d9df6029c5ace5f644ad279f48f95a35f1de0f96..eb9cec7419636f535bd0416128502d0cc6f6eb3b 100644 (file)
@@ -452,6 +452,7 @@ public:
   bool is_unsafe () const { return unsafety == Unsafety::Unsafe; }
   bool is_async () const { return async_status == Async::Yes; }
 
+  Unsafety get_unsafety () const { return unsafety; }
   ABI get_abi () const { return abi; }
 };
 
index 39772b42a0db48fbffda8ee4f102602e919cc2bd..dfefae8bef3e0c4ea41359b05fd0277780b84e38 100644 (file)
@@ -105,9 +105,12 @@ TypeCheckType::visit (HIR::BareFunctionType &fntype)
       params.emplace_back (ptype->get_ref ());
     }
 
-  translated = new TyTy::FnPtr (fntype.get_mappings ().get_hirid (),
-                               fntype.get_locus (), std::move (params),
-                               TyTy::TyVar (return_type->get_ref ()));
+  translated
+    = new TyTy::FnPtr (fntype.get_mappings ().get_hirid (), fntype.get_locus (),
+                      std::move (params),
+                      TyTy::TyVar (return_type->get_ref ()),
+                      fntype.get_function_qualifiers ().get_abi (),
+                      fntype.get_function_qualifiers ().get_unsafety ());
 }
 
 void
index 15d4a5920591a3c8f8e0aef55768a984df459629..9c1a84f5919a271e63ea7c32adbfa2244ae71963 100644 (file)
@@ -608,8 +608,8 @@ BaseType::monomorphized_clone () const
 
       TyVar retty = fn->get_var_return_type ().monomorphized_clone ();
       return new FnPtr (fn->get_ref (), fn->get_ty_ref (), ident.locus,
-                       std::move (cloned_params), retty,
-                       fn->get_combined_refs ());
+                       std::move (cloned_params), retty, fn->get_abi (),
+                       fn->get_unsafety (), fn->get_combined_refs ());
     }
   else if (auto adt = x->try_as<const ADTType> ())
     {
@@ -2268,7 +2268,13 @@ FnPtr::as_string () const
       params_str += p.get_tyty ()->as_string () + " ,";
     }
 
-  return "fnptr (" + params_str + ") -> " + get_return_type ()->as_string ();
+  std::string unsafety = "";
+  if (get_unsafety () == Unsafety::Unsafe)
+    unsafety = "unsafe ";
+
+  std::string abi = get_string_from_abi (get_abi ());
+  return unsafety + "abi:" + abi + " " + "fnptr (" + params_str + ") -> "
+        + get_return_type ()->as_string ();
 }
 
 bool
@@ -2304,8 +2310,8 @@ FnPtr::clone () const
     cloned_params.emplace_back (p.get_ref ());
 
   return new FnPtr (get_ref (), get_ty_ref (), ident.locus,
-                   std::move (cloned_params), result_type,
-                   get_combined_refs ());
+                   std::move (cloned_params), result_type, get_abi (),
+                   get_unsafety (), get_combined_refs ());
 }
 
 void
index 22aa28d6fe15174f2dbf7348f047593d8b00ada4..973ada3bdc42c856eb49d36468e3e72ad0245bba 100644 (file)
@@ -1046,19 +1046,22 @@ public:
   static constexpr auto KIND = TypeKind::FNPTR;
 
   FnPtr (HirId ref, location_t locus, std::vector<TyVar> params,
-        TyVar result_type, std::set<HirId> refs = std::set<HirId> ())
+        TyVar result_type, ABI abi, Unsafety unsafety,
+        std::set<HirId> refs = std::set<HirId> ())
     : CallableTypeInterface (ref, ref, TypeKind::FNPTR,
                             {Resolver::CanonicalPath::create_empty (), locus},
                             refs),
-      params (std::move (params)), result_type (result_type)
+      params (std::move (params)), result_type (result_type), abi (abi),
+      unsafety (unsafety)
   {}
 
   FnPtr (HirId ref, HirId ty_ref, location_t locus, std::vector<TyVar> params,
-        TyVar result_type, std::set<HirId> refs = std::set<HirId> ())
+        TyVar result_type, ABI abi, Unsafety unsafety,
+        std::set<HirId> refs = std::set<HirId> ())
     : CallableTypeInterface (ref, ty_ref, TypeKind::FNPTR,
                             {Resolver::CanonicalPath::create_empty (), locus},
                             refs),
-      params (params), result_type (result_type)
+      params (params), result_type (result_type), abi (abi), unsafety (unsafety)
   {}
 
   std::string get_name () const override final { return as_string (); }
@@ -1094,9 +1097,15 @@ public:
   std::vector<TyVar> &get_params () { return params; }
   const std::vector<TyVar> &get_params () const { return params; }
 
+  ABI get_abi () const { return abi; }
+
+  Unsafety get_unsafety () const { return unsafety; }
+
 private:
   std::vector<TyVar> params;
   TyVar result_type;
+  ABI abi;
+  Unsafety unsafety;
 };
 
 class ClosureType : public CallableTypeInterface, public SubstitutionRef
index 5ab1020d5967d1b14c7c444435092833fec4bf7d..be7ac51962b5c35e82dea87d2ee47f4276553acd 100644 (file)
@@ -1146,6 +1146,16 @@ UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype)
            return unify_error_type_node ();
          }
 
+       if (ltype->get_abi () != type.get_abi ())
+         {
+           return unify_error_type_node ();
+         }
+
+       if (ltype->get_unsafety () != type.get_unsafety ())
+         {
+           return unify_error_type_node ();
+         }
+
        return ltype;
       }
       break;
@@ -1183,6 +1193,25 @@ UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype)
              }
          }
 
+       // FIXME
+       //
+       // there is a bug in:
+       // testsuite/rust/compile/try-catch-unwind-{new,old}.rs I think the test
+       //
+       // case is wrong because it should be taking an FnOnce which probably
+       // didnt exist at the time in gccrs
+       //
+       // if (ltype->get_abi () != type.get_abi ())
+       //   {
+       //     return unify_error_type_node ();
+       //   }
+
+       // FIXME fntype needs to track unsafe or not
+       // if (ltype->get_unsafety () != type.get_unsafety ())
+       //   {
+       //     return unify_error_type_node ();
+       //   }
+
        return ltype;
       }
       break;