Skip to content

Commit 860ae72

Browse files
committed
gccrs: track abi and unsafety on fnptrs for proper type checking
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 #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]>
1 parent b7c9aaa commit 860ae72

File tree

5 files changed

+60
-12
lines changed

5 files changed

+60
-12
lines changed

gcc/rust/hir/tree/rust-hir-item.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,7 @@ struct FunctionQualifiers
452452
bool is_unsafe () const { return unsafety == Unsafety::Unsafe; }
453453
bool is_async () const { return async_status == Async::Yes; }
454454

455+
Unsafety get_unsafety () const { return unsafety; }
455456
ABI get_abi () const { return abi; }
456457
};
457458

gcc/rust/typecheck/rust-hir-type-check-type.cc

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,12 @@ TypeCheckType::visit (HIR::BareFunctionType &fntype)
105105
params.emplace_back (ptype->get_ref ());
106106
}
107107

108-
translated = new TyTy::FnPtr (fntype.get_mappings ().get_hirid (),
109-
fntype.get_locus (), std::move (params),
110-
TyTy::TyVar (return_type->get_ref ()));
108+
translated
109+
= new TyTy::FnPtr (fntype.get_mappings ().get_hirid (), fntype.get_locus (),
110+
std::move (params),
111+
TyTy::TyVar (return_type->get_ref ()),
112+
fntype.get_function_qualifiers ().get_abi (),
113+
fntype.get_function_qualifiers ().get_unsafety ());
111114
}
112115

113116
void

gcc/rust/typecheck/rust-tyty.cc

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -608,8 +608,8 @@ BaseType::monomorphized_clone () const
608608

609609
TyVar retty = fn->get_var_return_type ().monomorphized_clone ();
610610
return new FnPtr (fn->get_ref (), fn->get_ty_ref (), ident.locus,
611-
std::move (cloned_params), retty,
612-
fn->get_combined_refs ());
611+
std::move (cloned_params), retty, fn->get_abi (),
612+
fn->get_unsafety (), fn->get_combined_refs ());
613613
}
614614
else if (auto adt = x->try_as<const ADTType> ())
615615
{
@@ -2268,7 +2268,13 @@ FnPtr::as_string () const
22682268
params_str += p.get_tyty ()->as_string () + " ,";
22692269
}
22702270

2271-
return "fnptr (" + params_str + ") -> " + get_return_type ()->as_string ();
2271+
std::string unsafety = "";
2272+
if (get_unsafety () == Unsafety::Unsafe)
2273+
unsafety = "unsafe ";
2274+
2275+
std::string abi = get_string_from_abi (get_abi ());
2276+
return unsafety + "abi:" + abi + " " + "fnptr (" + params_str + ") -> "
2277+
+ get_return_type ()->as_string ();
22722278
}
22732279

22742280
bool
@@ -2304,8 +2310,8 @@ FnPtr::clone () const
23042310
cloned_params.emplace_back (p.get_ref ());
23052311

23062312
return new FnPtr (get_ref (), get_ty_ref (), ident.locus,
2307-
std::move (cloned_params), result_type,
2308-
get_combined_refs ());
2313+
std::move (cloned_params), result_type, get_abi (),
2314+
get_unsafety (), get_combined_refs ());
23092315
}
23102316

23112317
void

gcc/rust/typecheck/rust-tyty.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,19 +1046,22 @@ class FnPtr : public CallableTypeInterface
10461046
static constexpr auto KIND = TypeKind::FNPTR;
10471047

10481048
FnPtr (HirId ref, location_t locus, std::vector<TyVar> params,
1049-
TyVar result_type, std::set<HirId> refs = std::set<HirId> ())
1049+
TyVar result_type, ABI abi, Unsafety unsafety,
1050+
std::set<HirId> refs = std::set<HirId> ())
10501051
: CallableTypeInterface (ref, ref, TypeKind::FNPTR,
10511052
{Resolver::CanonicalPath::create_empty (), locus},
10521053
refs),
1053-
params (std::move (params)), result_type (result_type)
1054+
params (std::move (params)), result_type (result_type), abi (abi),
1055+
unsafety (unsafety)
10541056
{}
10551057

10561058
FnPtr (HirId ref, HirId ty_ref, location_t locus, std::vector<TyVar> params,
1057-
TyVar result_type, std::set<HirId> refs = std::set<HirId> ())
1059+
TyVar result_type, ABI abi, Unsafety unsafety,
1060+
std::set<HirId> refs = std::set<HirId> ())
10581061
: CallableTypeInterface (ref, ty_ref, TypeKind::FNPTR,
10591062
{Resolver::CanonicalPath::create_empty (), locus},
10601063
refs),
1061-
params (params), result_type (result_type)
1064+
params (params), result_type (result_type), abi (abi), unsafety (unsafety)
10621065
{}
10631066

10641067
std::string get_name () const override final { return as_string (); }
@@ -1094,9 +1097,15 @@ class FnPtr : public CallableTypeInterface
10941097
std::vector<TyVar> &get_params () { return params; }
10951098
const std::vector<TyVar> &get_params () const { return params; }
10961099

1100+
ABI get_abi () const { return abi; }
1101+
1102+
Unsafety get_unsafety () const { return unsafety; }
1103+
10971104
private:
10981105
std::vector<TyVar> params;
10991106
TyVar result_type;
1107+
ABI abi;
1108+
Unsafety unsafety;
11001109
};
11011110

11021111
class ClosureType : public CallableTypeInterface, public SubstitutionRef

gcc/rust/typecheck/rust-unify.cc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,6 +1146,16 @@ UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype)
11461146
return unify_error_type_node ();
11471147
}
11481148

1149+
if (ltype->get_abi () != type.get_abi ())
1150+
{
1151+
return unify_error_type_node ();
1152+
}
1153+
1154+
if (ltype->get_unsafety () != type.get_unsafety ())
1155+
{
1156+
return unify_error_type_node ();
1157+
}
1158+
11491159
return ltype;
11501160
}
11511161
break;
@@ -1183,6 +1193,25 @@ UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype)
11831193
}
11841194
}
11851195

1196+
// FIXME
1197+
//
1198+
// there is a bug in:
1199+
// testsuite/rust/compile/try-catch-unwind-{new,old}.rs I think the test
1200+
//
1201+
// case is wrong because it should be taking an FnOnce which probably
1202+
// didnt exist at the time in gccrs
1203+
//
1204+
// if (ltype->get_abi () != type.get_abi ())
1205+
// {
1206+
// return unify_error_type_node ();
1207+
// }
1208+
1209+
// FIXME fntype needs to track unsafe or not
1210+
// if (ltype->get_unsafety () != type.get_unsafety ())
1211+
// {
1212+
// return unify_error_type_node ();
1213+
// }
1214+
11861215
return ltype;
11871216
}
11881217
break;

0 commit comments

Comments
 (0)