From: Philip Herron <[email protected]>
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 <[email protected]>
---
gcc/rust/hir/tree/rust-hir-item.h | 1 +
.../typecheck/rust-hir-type-check-type.cc | 9 ++++--
gcc/rust/typecheck/rust-tyty.cc | 16 ++++++----
gcc/rust/typecheck/rust-tyty.h | 17 ++++++++---
gcc/rust/typecheck/rust-unify.cc | 29 +++++++++++++++++++
5 files changed, 60 insertions(+), 12 deletions(-)
diff --git a/gcc/rust/hir/tree/rust-hir-item.h
b/gcc/rust/hir/tree/rust-hir-item.h
index d9df6029c5a..eb9cec74196 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -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; }
};
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc
b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index 39772b42a0d..dfefae8bef3 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -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
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 15d4a592059..9c1a84f5919 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -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
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 22aa28d6fe1..973ada3bdc4 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -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
diff --git a/gcc/rust/typecheck/rust-unify.cc b/gcc/rust/typecheck/rust-unify.cc
index 5ab1020d596..be7ac51962b 100644
--- a/gcc/rust/typecheck/rust-unify.cc
+++ b/gcc/rust/typecheck/rust-unify.cc
@@ -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;
--
2.50.1