Skip to content

Commit 73fd349

Browse files
committed
Deprecate FnBox. Box<dyn FnOnce()> can be called directly, since 1.35
FCP completion: #28796 (comment)
1 parent a8fc09b commit 73fd349

File tree

4 files changed

+52
-31
lines changed

4 files changed

+52
-31
lines changed

src/liballoc/boxed.rs

+33-9
Original file line numberDiff line numberDiff line change
@@ -759,13 +759,14 @@ impl<A, F: Fn<A> + ?Sized> Fn<A> for Box<F> {
759759
}
760760
}
761761

762+
/// `FnBox` is deprecated and will be removed.
763+
/// `Box<dyn FnOnce()>` can be called directly, since Rust 1.35.0.
764+
///
762765
/// `FnBox` is a version of the `FnOnce` intended for use with boxed
763-
/// closure objects. The idea is that where one would normally store a
764-
/// `Box<dyn FnOnce()>` in a data structure, you should use
766+
/// closure objects. The idea was that where one would normally store a
767+
/// `Box<dyn FnOnce()>` in a data structure, you whould use
765768
/// `Box<dyn FnBox()>`. The two traits behave essentially the same, except
766-
/// that a `FnBox` closure can only be called if it is boxed. (Note
767-
/// that `FnBox` may be deprecated in the future if `Box<dyn FnOnce()>`
768-
/// closures become directly usable.)
769+
/// that a `FnBox` closure can only be called if it is boxed.
769770
///
770771
/// # Examples
771772
///
@@ -777,6 +778,7 @@ impl<A, F: Fn<A> + ?Sized> Fn<A> for Box<F> {
777778
///
778779
/// ```
779780
/// #![feature(fnbox)]
781+
/// #![allow(deprecated)]
780782
///
781783
/// use std::boxed::FnBox;
782784
/// use std::collections::HashMap;
@@ -796,16 +798,38 @@ impl<A, F: Fn<A> + ?Sized> Fn<A> for Box<F> {
796798
/// }
797799
/// }
798800
/// ```
801+
///
802+
/// In Rust 1.35.0 or later, use `FnOnce`, `FnMut`, or `Fn` instead:
803+
///
804+
/// ```
805+
/// use std::collections::HashMap;
806+
///
807+
/// fn make_map() -> HashMap<i32, Box<dyn FnOnce() -> i32>> {
808+
/// let mut map: HashMap<i32, Box<dyn FnOnce() -> i32>> = HashMap::new();
809+
/// map.insert(1, Box::new(|| 22));
810+
/// map.insert(2, Box::new(|| 44));
811+
/// map
812+
/// }
813+
///
814+
/// fn main() {
815+
/// let mut map = make_map();
816+
/// for i in &[1, 2] {
817+
/// let f = map.remove(&i).unwrap();
818+
/// assert_eq!(f(), i * 22);
819+
/// }
820+
/// }
821+
/// ```
799822
#[rustc_paren_sugar]
800-
#[unstable(feature = "fnbox",
801-
reason = "will be deprecated if and when `Box<FnOnce>` becomes usable", issue = "28796")]
823+
#[unstable(feature = "fnbox", issue = "28796")]
824+
#[rustc_deprecated(reason = "use `FnOnce`, `FnMut`, or `Fn` instead", since = "1.37.0")]
802825
pub trait FnBox<A>: FnOnce<A> {
803826
/// Performs the call operation.
804827
fn call_box(self: Box<Self>, args: A) -> Self::Output;
805828
}
806829

807-
#[unstable(feature = "fnbox",
808-
reason = "will be deprecated if and when `Box<FnOnce>` becomes usable", issue = "28796")]
830+
#[unstable(feature = "fnbox", issue = "28796")]
831+
#[rustc_deprecated(reason = "use `FnOnce`, `FnMut`, or `Fn` instead", since = "1.37.0")]
832+
#[allow(deprecated, deprecated_in_future)]
809833
impl<A, F> FnBox<A> for F
810834
where F: FnOnce<A>
811835
{

src/test/run-pass/unsized-locals/fnbox-compat.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![feature(fnbox)]
2+
#![allow(deprecated, deprecated_in_future)]
23

34
use std::boxed::FnBox;
45

src/test/ui/confuse-field-and-method/issue-2392.rs

+4-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
#![feature(core, fnbox)]
2-
3-
use std::boxed::FnBox;
4-
51
struct FuncContainer {
62
f1: fn(data: u8),
73
f2: extern "C" fn(data: u8),
@@ -18,7 +14,7 @@ struct Obj<F> where F: FnOnce() -> u32 {
1814
}
1915

2016
struct BoxedObj {
21-
boxed_closure: Box<FnBox() -> u32>,
17+
boxed_closure: Box<FnOnce() -> u32>,
2218
}
2319

2420
struct Wrapper<F> where F: FnMut() -> u32 {
@@ -29,8 +25,8 @@ fn func() -> u32 {
2925
0
3026
}
3127

32-
fn check_expression() -> Obj<Box<FnBox() -> u32>> {
33-
Obj { closure: Box::new(|| 42_u32) as Box<FnBox() -> u32>, not_closure: 42 }
28+
fn check_expression() -> Obj<Box<FnOnce() -> u32>> {
29+
Obj { closure: Box::new(|| 42_u32) as Box<FnOnce() -> u32>, not_closure: 42 }
3430
}
3531

3632
fn main() {
@@ -48,7 +44,7 @@ fn main() {
4844
let boxed_fn = BoxedObj { boxed_closure: Box::new(func) };
4945
boxed_fn.boxed_closure();//~ ERROR no method named `boxed_closure` found
5046

51-
let boxed_closure = BoxedObj { boxed_closure: Box::new(|| 42_u32) as Box<FnBox() -> u32> };
47+
let boxed_closure = BoxedObj { boxed_closure: Box::new(|| 42_u32) as Box<FnOnce() -> u32> };
5248
boxed_closure.boxed_closure();//~ ERROR no method named `boxed_closure` found
5349

5450
// test expression writing in the notes

src/test/ui/confuse-field-and-method/issue-2392.stderr

+14-14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
error[E0599]: no method named `closure` found for type `Obj<[closure@$DIR/issue-2392.rs:39:36: 39:41]>` in the current scope
2-
--> $DIR/issue-2392.rs:40:15
1+
error[E0599]: no method named `closure` found for type `Obj<[closure@$DIR/issue-2392.rs:35:36: 35:41]>` in the current scope
2+
--> $DIR/issue-2392.rs:36:15
33
|
44
LL | struct Obj<F> where F: FnOnce() -> u32 {
55
| -------------------------------------- method `closure` not found for this
@@ -11,8 +11,8 @@ help: to call the function stored in `closure`, surround the field access with p
1111
LL | (o_closure.closure)();
1212
| ^ ^
1313

14-
error[E0599]: no method named `not_closure` found for type `Obj<[closure@$DIR/issue-2392.rs:39:36: 39:41]>` in the current scope
15-
--> $DIR/issue-2392.rs:42:15
14+
error[E0599]: no method named `not_closure` found for type `Obj<[closure@$DIR/issue-2392.rs:35:36: 35:41]>` in the current scope
15+
--> $DIR/issue-2392.rs:38:15
1616
|
1717
LL | struct Obj<F> where F: FnOnce() -> u32 {
1818
| -------------------------------------- method `not_closure` not found for this
@@ -23,7 +23,7 @@ LL | o_closure.not_closure();
2323
| field, not a method
2424

2525
error[E0599]: no method named `closure` found for type `Obj<fn() -> u32 {func}>` in the current scope
26-
--> $DIR/issue-2392.rs:46:12
26+
--> $DIR/issue-2392.rs:42:12
2727
|
2828
LL | struct Obj<F> where F: FnOnce() -> u32 {
2929
| -------------------------------------- method `closure` not found for this
@@ -36,7 +36,7 @@ LL | (o_func.closure)();
3636
| ^ ^
3737

3838
error[E0599]: no method named `boxed_closure` found for type `BoxedObj` in the current scope
39-
--> $DIR/issue-2392.rs:49:14
39+
--> $DIR/issue-2392.rs:45:14
4040
|
4141
LL | struct BoxedObj {
4242
| --------------- method `boxed_closure` not found for this
@@ -49,7 +49,7 @@ LL | (boxed_fn.boxed_closure)();
4949
| ^ ^
5050

5151
error[E0599]: no method named `boxed_closure` found for type `BoxedObj` in the current scope
52-
--> $DIR/issue-2392.rs:52:19
52+
--> $DIR/issue-2392.rs:48:19
5353
|
5454
LL | struct BoxedObj {
5555
| --------------- method `boxed_closure` not found for this
@@ -62,7 +62,7 @@ LL | (boxed_closure.boxed_closure)();
6262
| ^ ^
6363

6464
error[E0599]: no method named `closure` found for type `Obj<fn() -> u32 {func}>` in the current scope
65-
--> $DIR/issue-2392.rs:57:12
65+
--> $DIR/issue-2392.rs:53:12
6666
|
6767
LL | struct Obj<F> where F: FnOnce() -> u32 {
6868
| -------------------------------------- method `closure` not found for this
@@ -75,7 +75,7 @@ LL | (w.wrap.closure)();
7575
| ^ ^
7676

7777
error[E0599]: no method named `not_closure` found for type `Obj<fn() -> u32 {func}>` in the current scope
78-
--> $DIR/issue-2392.rs:59:12
78+
--> $DIR/issue-2392.rs:55:12
7979
|
8080
LL | struct Obj<F> where F: FnOnce() -> u32 {
8181
| -------------------------------------- method `not_closure` not found for this
@@ -85,8 +85,8 @@ LL | w.wrap.not_closure();
8585
| |
8686
| field, not a method
8787

88-
error[E0599]: no method named `closure` found for type `Obj<std::boxed::Box<(dyn std::boxed::FnBox<(), Output = u32> + 'static)>>` in the current scope
89-
--> $DIR/issue-2392.rs:62:24
88+
error[E0599]: no method named `closure` found for type `Obj<std::boxed::Box<(dyn std::ops::FnOnce() -> u32 + 'static)>>` in the current scope
89+
--> $DIR/issue-2392.rs:58:24
9090
|
9191
LL | struct Obj<F> where F: FnOnce() -> u32 {
9292
| -------------------------------------- method `closure` not found for this
@@ -99,7 +99,7 @@ LL | (check_expression().closure)();
9999
| ^ ^
100100

101101
error[E0599]: no method named `f1` found for type `FuncContainer` in the current scope
102-
--> $DIR/issue-2392.rs:68:31
102+
--> $DIR/issue-2392.rs:64:31
103103
|
104104
LL | struct FuncContainer {
105105
| -------------------- method `f1` not found for this
@@ -112,7 +112,7 @@ LL | ((*self.container).f1)(1);
112112
| ^ ^
113113

114114
error[E0599]: no method named `f2` found for type `FuncContainer` in the current scope
115-
--> $DIR/issue-2392.rs:69:31
115+
--> $DIR/issue-2392.rs:65:31
116116
|
117117
LL | struct FuncContainer {
118118
| -------------------- method `f2` not found for this
@@ -125,7 +125,7 @@ LL | ((*self.container).f2)(1);
125125
| ^ ^
126126

127127
error[E0599]: no method named `f3` found for type `FuncContainer` in the current scope
128-
--> $DIR/issue-2392.rs:70:31
128+
--> $DIR/issue-2392.rs:66:31
129129
|
130130
LL | struct FuncContainer {
131131
| -------------------- method `f3` not found for this

0 commit comments

Comments
 (0)