Skip to content

Commit 1eaee67

Browse files
committed
Fix fnptr not auto implement fn once
gcc/rust/ChangeLog: * typecheck/rust-tyty.cc (FnPtr::setup_fn_once_output): Fix fnptr not auto implement fn once * typecheck/rust-tyty.h: Likewise. gcc/testsuite/ChangeLog: * rust/compile/format_args_basic_expansion.rs: add sized and fn_once * rust/compile/issue-2042.rs: add sized and fn_once * rust/compile/privacy6.rs: add sized and fn_once * rust/compile/rust_abi.rs: add sized and fn_once * rust/compile/torture/function_reference2.rs: add sized and fn_once * rust/compile/torture/function_reference3.rs: add sized and fn_once * rust/compile/torture/function_reference4.rs: add sized and fn_once * rust/compile/try-catch-unwind-new.rs: add sized and fn_once * rust/compile/try-catch-unwind-old.rs: add sized and fn_once
1 parent 6029cc9 commit 1eaee67

11 files changed

+156
-2
lines changed

gcc/rust/typecheck/rust-tyty.cc

+50
Original file line numberDiff line numberDiff line change
@@ -2222,6 +2222,56 @@ FnPtr::clone () const
22222222
get_combined_refs ());
22232223
}
22242224

2225+
void
2226+
FnPtr::setup_fn_once_output () const
2227+
{
2228+
// lookup the lang items
2229+
auto fn_once_lookup = mappings.lookup_lang_item (LangItem::Kind::FN_ONCE);
2230+
auto fn_once_output_lookup
2231+
= mappings.lookup_lang_item (LangItem::Kind::FN_ONCE_OUTPUT);
2232+
if (!fn_once_lookup)
2233+
{
2234+
rust_fatal_error (UNKNOWN_LOCATION,
2235+
"Missing required %<fn_once%> lang item");
2236+
return;
2237+
}
2238+
if (!fn_once_output_lookup)
2239+
{
2240+
rust_fatal_error (UNKNOWN_LOCATION,
2241+
"Missing required %<fn_once_ouput%> lang item");
2242+
return;
2243+
}
2244+
2245+
DefId &trait_id = fn_once_lookup.value ();
2246+
DefId &trait_item_id = fn_once_output_lookup.value ();
2247+
2248+
// resolve to the trait
2249+
HIR::Item *item = mappings.lookup_defid (trait_id).value ();
2250+
rust_assert (item->get_item_kind () == HIR::Item::ItemKind::Trait);
2251+
HIR::Trait *trait = static_cast<HIR::Trait *> (item);
2252+
2253+
Resolver::TraitReference *trait_ref
2254+
= Resolver::TraitResolver::Resolve (*trait);
2255+
rust_assert (!trait_ref->is_error ());
2256+
2257+
// resolve to trait item
2258+
HIR::TraitItem *trait_item
2259+
= mappings.lookup_trait_item_defid (trait_item_id).value ();
2260+
rust_assert (trait_item->get_item_kind ()
2261+
== HIR::TraitItem::TraitItemKind::TYPE);
2262+
std::string item_identifier = trait_item->trait_identifier ();
2263+
2264+
// setup associated types #[lang = "fn_once_output"]
2265+
Resolver::TraitItemReference *item_reference = nullptr;
2266+
bool found = trait_ref->lookup_trait_item_by_type (
2267+
item_identifier, Resolver::TraitItemReference::TraitItemType::TYPE,
2268+
&item_reference);
2269+
rust_assert (found);
2270+
2271+
// setup
2272+
item_reference->associated_type_set (&get_result_type ());
2273+
}
2274+
22252275
void
22262276
ClosureType::accept_vis (TyVisitor &vis)
22272277
{

gcc/rust/typecheck/rust-tyty.h

+9-2
Original file line numberDiff line numberDiff line change
@@ -971,15 +971,19 @@ class FnPtr : public CallableTypeInterface
971971
{Resolver::CanonicalPath::create_empty (), locus},
972972
refs),
973973
params (std::move (params)), result_type (result_type)
974-
{}
974+
{
975+
setup_fn_once_output ();
976+
}
975977

976978
FnPtr (HirId ref, HirId ty_ref, location_t locus, std::vector<TyVar> params,
977979
TyVar result_type, std::set<HirId> refs = std::set<HirId> ())
978980
: CallableTypeInterface (ref, ty_ref, TypeKind::FNPTR,
979981
{Resolver::CanonicalPath::create_empty (), locus},
980982
refs),
981983
params (params), result_type (result_type)
982-
{}
984+
{
985+
setup_fn_once_output ();
986+
}
983987

984988
std::string get_name () const override final { return as_string (); }
985989

@@ -1000,6 +1004,7 @@ class FnPtr : public CallableTypeInterface
10001004

10011005
const TyVar &get_var_return_type () const { return result_type; }
10021006

1007+
TyTy::BaseType &get_result_type () const { return *result_type.get_tyty (); }
10031008
size_t num_params () const { return params.size (); }
10041009

10051010
void accept_vis (TyVisitor &vis) override;
@@ -1016,6 +1021,8 @@ class FnPtr : public CallableTypeInterface
10161021
std::vector<TyVar> &get_params () { return params; }
10171022
const std::vector<TyVar> &get_params () const { return params; }
10181023

1024+
void setup_fn_once_output () const;
1025+
10191026
private:
10201027
std::vector<TyVar> params;
10211028
TyVar result_type;

gcc/testsuite/rust/compile/format_args_basic_expansion.rs

+8
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ macro_rules! format_args {
88
#[lang = "sized"]
99
trait Sized {}
1010

11+
#[lang = "fn_once"]
12+
pub trait FnOnce<Args> {
13+
#[lang = "fn_once_output"]
14+
type Output;
15+
16+
extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
17+
}
18+
1119
pub mod core {
1220
pub mod fmt {
1321
pub struct Formatter;

gcc/testsuite/rust/compile/issue-2042.rs

+12
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
#[lang = "sized"]
2+
pub trait Sized {}
3+
4+
#[lang = "fn_once"]
5+
pub trait FnOnce<Args> {
6+
#[lang = "fn_once_output"]
7+
type Output;
8+
9+
extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
10+
}
11+
12+
113
fn f<'r>(p: &'r mut fn(p: &mut ())) {
214
(*p)(())
315
// { dg-error "expected .&mut ()." "" { target *-*-* } .-1 }

gcc/testsuite/rust/compile/privacy6.rs

+10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
2+
#[lang = "fn_once"]
3+
pub trait FnOnce<Args> {
4+
#[lang = "fn_once_output"]
5+
type Output;
6+
7+
extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
8+
}
9+
10+
111
// { dg-additional-options "-w" }
212

313
#[lang = "sized"]
+11
Original file line numberDiff line numberDiff line change
@@ -1 +1,12 @@
1+
#[lang = "sized"]
2+
pub trait Sized {}
3+
4+
#[lang = "fn_once"]
5+
pub trait FnOnce<Args> {
6+
#[lang = "fn_once_output"]
7+
type Output;
8+
9+
extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
10+
}
11+
112
pub fn f(_: extern "Rust" fn()) {}

gcc/testsuite/rust/compile/torture/function_reference2.rs

+11
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
#[lang = "sized"]
2+
pub trait Sized {}
3+
4+
#[lang = "fn_once"]
5+
pub trait FnOnce<Args> {
6+
#[lang = "fn_once_output"]
7+
type Output;
8+
9+
extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
10+
}
11+
112
fn test(a: i32) -> i32 {
213
a + 1
314
}

gcc/testsuite/rust/compile/torture/function_reference3.rs

+12
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
#[lang = "sized"]
2+
pub trait Sized {}
3+
4+
#[lang = "fn_once"]
5+
pub trait FnOnce<Args> {
6+
#[lang = "fn_once_output"]
7+
type Output;
8+
9+
extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
10+
}
11+
12+
113
struct Foo {
214
a: fn(i32) -> i32,
315
b: i32,

gcc/testsuite/rust/compile/torture/function_reference4.rs

+11
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
#[lang = "sized"]
2+
pub trait Sized {}
3+
4+
#[lang = "fn_once"]
5+
pub trait FnOnce<Args> {
6+
#[lang = "fn_once_output"]
7+
type Output;
8+
9+
extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
10+
}
11+
112
fn test(a: i32) -> i32 {
213
a + 1
314
}

gcc/testsuite/rust/compile/try-catch-unwind-new.rs

+11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
// { dg-options "-O2 -w -fdump-tree-optimized" }
22
#![feature(intrinsics)]
33

4+
#[lang = "sized"]
5+
pub trait Sized {}
6+
7+
#[lang = "fn_once"]
8+
pub trait FnOnce<Args> {
9+
#[lang = "fn_once_output"]
10+
type Output;
11+
12+
extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
13+
}
14+
415
extern "rust-intrinsic" {
516
// { dg-final { scan-tree-dump-times "__builtin_eh_pointer" 1 "optimized" } }
617
fn catch_unwind(try_fn: fn(_: *mut u8), data: *mut u8, catch_fn: fn(_: *mut u8, _: *mut u8));

gcc/testsuite/rust/compile/try-catch-unwind-old.rs

+11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
// { dg-options "-O2 -w -fdump-tree-optimized" }
22
#![feature(intrinsics)]
33

4+
#[lang = "sized"]
5+
pub trait Sized {}
6+
7+
#[lang = "fn_once"]
8+
pub trait FnOnce<Args> {
9+
#[lang = "fn_once_output"]
10+
type Output;
11+
12+
extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
13+
}
14+
415
extern "rust-intrinsic" {
516
// { dg-final { scan-tree-dump-times "__builtin_eh_pointer" 1 "optimized" } }
617
fn r#try(try_fn: fn(_: *mut u8), data: *mut u8, catch_fn: fn(_: *mut u8, _: *mut u8)) -> i32;

0 commit comments

Comments
 (0)