Skip to content

Commit

Permalink
Rollup merge of rust-lang#104113 - ink-feather-org:fix_const_fn_ref_i…
Browse files Browse the repository at this point in the history
…mpls, r=compiler-errors

Fix `const_fn_trait_ref_impl`, add test for it

rust-lang#99943 broke `#[feature(const_fn_trait_ref_impl)]`, this PR fixes this and adds a test for it.

r? `@fee1-dead`
  • Loading branch information
GuillaumeGomez authored Nov 8, 2022
2 parents 1827496 + 87c190c commit fb78d9c
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 10 deletions.
25 changes: 15 additions & 10 deletions library/core/src/ops/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -576,29 +576,32 @@ mod impls {
use crate::marker::Tuple;

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Tuple, F: ?Sized> Fn<A> for &F
#[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")]
impl<A: Tuple, F: ?Sized> const Fn<A> for &F
where
F: Fn<A>,
F: ~const Fn<A>,
{
extern "rust-call" fn call(&self, args: A) -> F::Output {
(**self).call(args)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Tuple, F: ?Sized> FnMut<A> for &F
#[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")]
impl<A: Tuple, F: ?Sized> const FnMut<A> for &F
where
F: Fn<A>,
F: ~const Fn<A>,
{
extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
(**self).call(args)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Tuple, F: ?Sized> FnOnce<A> for &F
#[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")]
impl<A: Tuple, F: ?Sized> const FnOnce<A> for &F
where
F: Fn<A>,
F: ~const Fn<A>,
{
type Output = F::Output;

Expand All @@ -608,19 +611,21 @@ mod impls {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Tuple, F: ?Sized> FnMut<A> for &mut F
#[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")]
impl<A: Tuple, F: ?Sized> const FnMut<A> for &mut F
where
F: FnMut<A>,
F: ~const FnMut<A>,
{
extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
(*self).call_mut(args)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Tuple, F: ?Sized> FnOnce<A> for &mut F
#[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")]
impl<A: Tuple, F: ?Sized> const FnOnce<A> for &mut F
where
F: FnMut<A>,
F: ~const FnMut<A>,
{
type Output = F::Output;
extern "rust-call" fn call_once(self, args: A) -> F::Output {
Expand Down
80 changes: 80 additions & 0 deletions src/test/ui/consts/fn_trait_refs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// build-pass

#![feature(const_fn_trait_ref_impls)]
#![feature(fn_traits)]
#![feature(unboxed_closures)]
#![feature(const_trait_impl)]
#![feature(const_mut_refs)]
#![feature(const_cmp)]
#![feature(const_refs_to_cell)]

use std::marker::Destruct;

const fn tester_fn<T>(f: T) -> T::Output
where
T: ~const Fn<()> + ~const Destruct,
{
f()
}

const fn tester_fn_mut<T>(mut f: T) -> T::Output
where
T: ~const FnMut<()> + ~const Destruct,
{
f()
}

const fn tester_fn_once<T>(f: T) -> T::Output
where
T: ~const FnOnce<()>,
{
f()
}

const fn test_fn<T>(mut f: T) -> (T::Output, T::Output, T::Output)
where
T: ~const Fn<()> + ~const Destruct,
{
(
// impl<A: Tuple, F: ~const Fn + ?Sized> const Fn<A> for &F
tester_fn(&f),
// impl<A: Tuple, F: ~const Fn + ?Sized> const FnMut<A> for &F
tester_fn_mut(&f),
// impl<A: Tuple, F: ~const Fn + ?Sized> const FnOnce<A> for &F
tester_fn_once(&f),
)
}

const fn test_fn_mut<T>(mut f: T) -> (T::Output, T::Output)
where
T: ~const FnMut<()> + ~const Destruct,
{
(
// impl<A: Tuple, F: ~const FnMut + ?Sized> const FnMut<A> for &mut F
tester_fn_mut(&mut f),
// impl<A: Tuple, F: ~const FnMut + ?Sized> const FnOnce<A> for &mut F
tester_fn_once(&mut f),
)
}
const fn test(i: i32) -> i32 {
i + 1
}

const fn main() {
const fn one() -> i32 {
1
};
const fn two() -> i32 {
2
};

// FIXME(const_cmp_tuple)
let test_one = test_fn(one);
assert!(test_one.0 == 1);
assert!(test_one.1 == 1);
assert!(test_one.2 == 1);

let test_two = test_fn_mut(two);
assert!(test_two.0 == 1);
assert!(test_two.1 == 1);
}

0 comments on commit fb78d9c

Please sign in to comment.