about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2022-11-08 20:40:51 +0100
committerGitHub <noreply@github.com>2022-11-08 20:40:51 +0100
commit02db37a18ab27e37d4edf9409f838c4549f24e24 (patch)
treee56d1a094609188167c9b67838e0224266667b4b
parentc39cf7acaab82e941ac09ef4c949921c2d2b6e89 (diff)
parent87c190c4252ce2039400146bbdf6b7245a5499f0 (diff)
downloadrust-02db37a18ab27e37d4edf9409f838c4549f24e24.tar.gz
rust-02db37a18ab27e37d4edf9409f838c4549f24e24.zip
Rollup merge of #104113 - ink-feather-org:fix_const_fn_ref_impls, r=compiler-errors
Fix `const_fn_trait_ref_impl`, add test for it

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

r? ````@fee1-dead````
-rw-r--r--library/core/src/ops/function.rs25
-rw-r--r--src/test/ui/consts/fn_trait_refs.rs80
2 files changed, 95 insertions, 10 deletions
diff --git a/library/core/src/ops/function.rs b/library/core/src/ops/function.rs
index 8d4b0a7ccac..11b43b621c7 100644
--- a/library/core/src/ops/function.rs
+++ b/library/core/src/ops/function.rs
@@ -576,9 +576,10 @@ 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)
@@ -586,9 +587,10 @@ mod impls {
     }
 
     #[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)
@@ -596,9 +598,10 @@ mod impls {
     }
 
     #[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;
 
@@ -608,9 +611,10 @@ 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)
@@ -618,9 +622,10 @@ mod impls {
     }
 
     #[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 {
diff --git a/src/test/ui/consts/fn_trait_refs.rs b/src/test/ui/consts/fn_trait_refs.rs
new file mode 100644
index 00000000000..bc8766c74c6
--- /dev/null
+++ b/src/test/ui/consts/fn_trait_refs.rs
@@ -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);
+}