Auto merge of #59500 - crlf0710:boxed-closure-impls, r=cramertj

Unsized rvalues: implement boxed closure impls. (2nd try)

This is a rebase of S-blocked-closed PR #55431 to current master. LLVM has moved forward since then, so maybe we can check whether the new LLVM 8.0 version unblocked this work.
This commit is contained in:
bors 2019-04-05 17:45:43 +00:00
commit acd8dd6a50
12 changed files with 119 additions and 100 deletions

View File

@ -0,0 +1,32 @@
# `fnbox`
The tracking issue for this feature is [#28796]
[#28796]: https://github.com/rust-lang/rust/issues/28796
------------------------
This had been a temporary alternative to the following impls:
```rust,ignore
impl<A, F> FnOnce for Box<F> where F: FnOnce<A> + ?Sized {}
impl<A, F> FnMut for Box<F> where F: FnMut<A> + ?Sized {}
impl<A, F> Fn for Box<F> where F: Fn<A> + ?Sized {}
```
The impls are parallel to these (relatively old) impls:
```rust,ignore
impl<A, F> FnOnce for &mut F where F: FnMut<A> + ?Sized {}
impl<A, F> FnMut for &mut F where F: FnMut<A> + ?Sized {}
impl<A, F> Fn for &mut F where F: Fn<A> + ?Sized {}
impl<A, F> FnOnce for &F where F: Fn<A> + ?Sized {}
impl<A, F> FnMut for &F where F: Fn<A> + ?Sized {}
impl<A, F> Fn for &F where F: Fn<A> + ?Sized {}
```
Before the introduction of [`unsized_locals`][unsized_locals], we had been unable to provide the former impls. That means, unlike `&dyn Fn()` or `&mut dyn FnMut()` we could not use `Box<dyn FnOnce()>` at that time.
[unsized_locals]: language-features/unsized-locals.html
`FnBox()` is an alternative approach to `Box<dyn FnBox()>` is delegated to `FnBox::call_box` which doesn't need unsized locals. As we now have `Box<dyn FnOnce()>` working, the `fnbox` feature is going to be removed.

View File

@ -694,6 +694,28 @@ impl<I: ExactSizeIterator + ?Sized> ExactSizeIterator for Box<I> {
#[stable(feature = "fused", since = "1.26.0")] #[stable(feature = "fused", since = "1.26.0")]
impl<I: FusedIterator + ?Sized> FusedIterator for Box<I> {} impl<I: FusedIterator + ?Sized> FusedIterator for Box<I> {}
#[stable(feature = "boxed_closure_impls", since = "1.35.0")]
impl<A, F: FnOnce<A> + ?Sized> FnOnce<A> for Box<F> {
type Output = <F as FnOnce<A>>::Output;
extern "rust-call" fn call_once(self, args: A) -> Self::Output {
<F as FnOnce<A>>::call_once(*self, args)
}
}
#[stable(feature = "boxed_closure_impls", since = "1.35.0")]
impl<A, F: FnMut<A> + ?Sized> FnMut<A> for Box<F> {
extern "rust-call" fn call_mut(&mut self, args: A) -> Self::Output {
<F as FnMut<A>>::call_mut(self, args)
}
}
#[stable(feature = "boxed_closure_impls", since = "1.35.0")]
impl<A, F: Fn<A> + ?Sized> Fn<A> for Box<F> {
extern "rust-call" fn call(&self, args: A) -> Self::Output {
<F as Fn<A>>::call(self, args)
}
}
/// `FnBox` is a version of the `FnOnce` intended for use with boxed /// `FnBox` is a version of the `FnOnce` intended for use with boxed
/// closure objects. The idea is that where one would normally store a /// closure objects. The idea is that where one would normally store a
@ -735,9 +757,7 @@ impl<I: FusedIterator + ?Sized> FusedIterator for Box<I> {}
#[rustc_paren_sugar] #[rustc_paren_sugar]
#[unstable(feature = "fnbox", #[unstable(feature = "fnbox",
reason = "will be deprecated if and when `Box<FnOnce>` becomes usable", issue = "28796")] reason = "will be deprecated if and when `Box<FnOnce>` becomes usable", issue = "28796")]
pub trait FnBox<A> { pub trait FnBox<A>: FnOnce<A> {
type Output;
fn call_box(self: Box<Self>, args: A) -> Self::Output; fn call_box(self: Box<Self>, args: A) -> Self::Output;
} }
@ -746,33 +766,11 @@ pub trait FnBox<A> {
impl<A, F> FnBox<A> for F impl<A, F> FnBox<A> for F
where F: FnOnce<A> where F: FnOnce<A>
{ {
type Output = F::Output;
fn call_box(self: Box<F>, args: A) -> F::Output { fn call_box(self: Box<F>, args: A) -> F::Output {
self.call_once(args) self.call_once(args)
} }
} }
#[unstable(feature = "fnbox",
reason = "will be deprecated if and when `Box<FnOnce>` becomes usable", issue = "28796")]
impl<A, R> FnOnce<A> for Box<dyn FnBox<A, Output = R> + '_> {
type Output = R;
extern "rust-call" fn call_once(self, args: A) -> R {
self.call_box(args)
}
}
#[unstable(feature = "fnbox",
reason = "will be deprecated if and when `Box<FnOnce>` becomes usable", issue = "28796")]
impl<A, R> FnOnce<A> for Box<dyn FnBox<A, Output = R> + Send + '_> {
type Output = R;
extern "rust-call" fn call_once(self, args: A) -> R {
self.call_box(args)
}
}
#[unstable(feature = "coerce_unsized", issue = "27732")] #[unstable(feature = "coerce_unsized", issue = "27732")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Box<U>> for Box<T> {} impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Box<U>> for Box<T> {}

View File

@ -107,6 +107,7 @@
#![feature(unboxed_closures)] #![feature(unboxed_closures)]
#![feature(unicode_internals)] #![feature(unicode_internals)]
#![feature(unsize)] #![feature(unsize)]
#![feature(unsized_locals)]
#![feature(allocator_internals)] #![feature(allocator_internals)]
#![feature(on_unimplemented)] #![feature(on_unimplemented)]
#![feature(rustc_const_unstable)] #![feature(rustc_const_unstable)]

View File

@ -0,0 +1,8 @@
fn call_it<T>(f: Box<dyn FnOnce() -> T>) -> T {
f()
}
fn main() {
let s = "hello".to_owned();
assert_eq!(&call_it(Box::new(|| s)) as &str, "hello");
}

View File

@ -0,0 +1,12 @@
#![feature(fnbox)]
use std::boxed::FnBox;
fn call_it<T>(f: Box<dyn FnBox() -> T>) -> T {
f()
}
fn main() {
let s = "hello".to_owned();
assert_eq!(&call_it(Box::new(|| s)) as &str, "hello");
}

View File

@ -7,17 +7,15 @@ LL | f(f(10));
| first mutable borrow occurs here | first mutable borrow occurs here
| first borrow later used by call | first borrow later used by call
error[E0382]: use of moved value: `*f` error[E0382]: use of moved value: `f`
--> $DIR/two-phase-nonrecv-autoref.rs:69:11 --> $DIR/two-phase-nonrecv-autoref.rs:69:11
| |
LL | fn twice_ten_so<F: FnOnce(i32) -> i32>(f: Box<F>) { LL | fn twice_ten_so<F: FnOnce(i32) -> i32>(f: Box<F>) {
| - consider adding a `Copy` constraint to this type argument | - move occurs because `f` has type `std::boxed::Box<F>`, which does not implement the `Copy` trait
LL | f(f(10)); LL | f(f(10));
| - ^ value used here after move | - ^ value used here after move
| | | |
| value moved here | value moved here
|
= note: move occurs because `*f` has type `F`, which does not implement the `Copy` trait
error[E0499]: cannot borrow `*f` as mutable more than once at a time error[E0499]: cannot borrow `*f` as mutable more than once at a time
--> $DIR/two-phase-nonrecv-autoref.rs:76:11 --> $DIR/two-phase-nonrecv-autoref.rs:76:11
@ -28,30 +26,18 @@ LL | f(f(10));
| first mutable borrow occurs here | first mutable borrow occurs here
| first borrow later used by call | first borrow later used by call
error[E0161]: cannot move a value of type dyn std::ops::FnOnce(i32) -> i32: the size of dyn std::ops::FnOnce(i32) -> i32 cannot be statically determined error[E0382]: use of moved value: `f`
--> $DIR/two-phase-nonrecv-autoref.rs:85:9
|
LL | f(f(10));
| ^
error[E0161]: cannot move a value of type dyn std::ops::FnOnce(i32) -> i32: the size of dyn std::ops::FnOnce(i32) -> i32 cannot be statically determined
--> $DIR/two-phase-nonrecv-autoref.rs:85:11
|
LL | f(f(10));
| ^
error[E0382]: use of moved value: `*f`
--> $DIR/two-phase-nonrecv-autoref.rs:85:11 --> $DIR/two-phase-nonrecv-autoref.rs:85:11
| |
LL | fn twice_ten_oo(f: Box<FnOnce(i32) -> i32>) {
| - move occurs because `f` has type `std::boxed::Box<dyn std::ops::FnOnce(i32) -> i32>`, which does not implement the `Copy` trait
LL | f(f(10)); LL | f(f(10));
| - ^ value used here after move | - ^ value used here after move
| | | |
| value moved here | value moved here
|
= note: move occurs because `*f` has type `dyn std::ops::FnOnce(i32) -> i32`, which does not implement the `Copy` trait
error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable
--> $DIR/two-phase-nonrecv-autoref.rs:129:27 --> $DIR/two-phase-nonrecv-autoref.rs:125:27
| |
LL | double_access(&mut a, &a); LL | double_access(&mut a, &a);
| ------------- ------ ^^ immutable borrow occurs here | ------------- ------ ^^ immutable borrow occurs here
@ -60,7 +46,7 @@ LL | double_access(&mut a, &a);
| mutable borrow later used by call | mutable borrow later used by call
error[E0502]: cannot borrow `i` as immutable because it is also borrowed as mutable error[E0502]: cannot borrow `i` as immutable because it is also borrowed as mutable
--> $DIR/two-phase-nonrecv-autoref.rs:157:7 --> $DIR/two-phase-nonrecv-autoref.rs:153:7
| |
LL | i[i[3]] = 4; LL | i[i[3]] = 4;
| --^---- | --^----
@ -70,7 +56,7 @@ LL | i[i[3]] = 4;
| mutable borrow later used here | mutable borrow later used here
error[E0502]: cannot borrow `i` as immutable because it is also borrowed as mutable error[E0502]: cannot borrow `i` as immutable because it is also borrowed as mutable
--> $DIR/two-phase-nonrecv-autoref.rs:163:7 --> $DIR/two-phase-nonrecv-autoref.rs:159:7
| |
LL | i[i[3]] = i[4]; LL | i[i[3]] = i[4];
| --^---- | --^----
@ -79,7 +65,7 @@ LL | i[i[3]] = i[4];
| mutable borrow occurs here | mutable borrow occurs here
| mutable borrow later used here | mutable borrow later used here
error: aborting due to 9 previous errors error: aborting due to 7 previous errors
Some errors occurred: E0161, E0382, E0499, E0502. Some errors occurred: E0382, E0499, E0502.
For more information about an error, try `rustc --explain E0161`. For more information about an error, try `rustc --explain E0382`.

View File

@ -15,7 +15,7 @@ LL | f(f(10));
| | second mutable borrow occurs here | | second mutable borrow occurs here
| first mutable borrow occurs here | first mutable borrow occurs here
error[E0382]: use of moved value: `*f` error[E0382]: use of moved value: `f`
--> $DIR/two-phase-nonrecv-autoref.rs:69:11 --> $DIR/two-phase-nonrecv-autoref.rs:69:11
| |
LL | f(f(10)); LL | f(f(10));
@ -23,7 +23,7 @@ LL | f(f(10));
| | | |
| value moved here | value moved here
| |
= note: move occurs because `*f` has type `F`, which does not implement the `Copy` trait = note: move occurs because `f` has type `std::boxed::Box<F>`, which does not implement the `Copy` trait
error[E0499]: cannot borrow `*f` as mutable more than once at a time error[E0499]: cannot borrow `*f` as mutable more than once at a time
--> $DIR/two-phase-nonrecv-autoref.rs:76:11 --> $DIR/two-phase-nonrecv-autoref.rs:76:11
@ -34,7 +34,7 @@ LL | f(f(10));
| | second mutable borrow occurs here | | second mutable borrow occurs here
| first mutable borrow occurs here | first mutable borrow occurs here
error[E0382]: use of moved value: `*f` error[E0382]: use of moved value: `f`
--> $DIR/two-phase-nonrecv-autoref.rs:85:11 --> $DIR/two-phase-nonrecv-autoref.rs:85:11
| |
LL | f(f(10)); LL | f(f(10));
@ -42,10 +42,10 @@ LL | f(f(10));
| | | |
| value moved here | value moved here
| |
= note: move occurs because `*f` has type `(dyn std::ops::FnOnce(i32) -> i32 + 'static)`, which does not implement the `Copy` trait = note: move occurs because `f` has type `std::boxed::Box<(dyn std::ops::FnOnce(i32) -> i32 + 'static)>`, which does not implement the `Copy` trait
error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable
--> $DIR/two-phase-nonrecv-autoref.rs:129:28 --> $DIR/two-phase-nonrecv-autoref.rs:125:28
| |
LL | double_access(&mut a, &a); LL | double_access(&mut a, &a);
| - ^- mutable borrow ends here | - ^- mutable borrow ends here
@ -54,7 +54,7 @@ LL | double_access(&mut a, &a);
| mutable borrow occurs here | mutable borrow occurs here
error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable
--> $DIR/two-phase-nonrecv-autoref.rs:135:9 --> $DIR/two-phase-nonrecv-autoref.rs:131:9
| |
LL | a.m(a.i(10)); LL | a.m(a.i(10));
| - ^ - mutable borrow ends here | - ^ - mutable borrow ends here
@ -63,7 +63,7 @@ LL | a.m(a.i(10));
| mutable borrow occurs here | mutable borrow occurs here
error[E0502]: cannot borrow `i` as immutable because it is also borrowed as mutable error[E0502]: cannot borrow `i` as immutable because it is also borrowed as mutable
--> $DIR/two-phase-nonrecv-autoref.rs:157:7 --> $DIR/two-phase-nonrecv-autoref.rs:153:7
| |
LL | i[i[3]] = 4; LL | i[i[3]] = 4;
| - ^ - mutable borrow ends here | - ^ - mutable borrow ends here
@ -72,7 +72,7 @@ LL | i[i[3]] = 4;
| mutable borrow occurs here | mutable borrow occurs here
error[E0502]: cannot borrow `i` as immutable because it is also borrowed as mutable error[E0502]: cannot borrow `i` as immutable because it is also borrowed as mutable
--> $DIR/two-phase-nonrecv-autoref.rs:163:7 --> $DIR/two-phase-nonrecv-autoref.rs:159:7
| |
LL | i[i[3]] = i[4]; LL | i[i[3]] = i[4];
| - ^ - mutable borrow ends here | - ^ - mutable borrow ends here
@ -81,7 +81,7 @@ LL | i[i[3]] = i[4];
| mutable borrow occurs here | mutable borrow occurs here
error[E0502]: cannot borrow `v` as immutable because it is also borrowed as mutable error[E0502]: cannot borrow `v` as immutable because it is also borrowed as mutable
--> $DIR/two-phase-nonrecv-autoref.rs:172:12 --> $DIR/two-phase-nonrecv-autoref.rs:168:12
| |
LL | v.push(v.len()); LL | v.push(v.len());
| - ^ - mutable borrow ends here | - ^ - mutable borrow ends here
@ -90,7 +90,7 @@ LL | v.push(v.len());
| mutable borrow occurs here | mutable borrow occurs here
error[E0502]: cannot borrow `s` as immutable because it is also borrowed as mutable error[E0502]: cannot borrow `s` as immutable because it is also borrowed as mutable
--> $DIR/two-phase-nonrecv-autoref.rs:183:9 --> $DIR/two-phase-nonrecv-autoref.rs:179:9
| |
LL | s.m(s.i(10)); LL | s.m(s.i(10));
| - ^ - mutable borrow ends here | - ^ - mutable borrow ends here
@ -99,7 +99,7 @@ LL | s.m(s.i(10));
| mutable borrow occurs here | mutable borrow occurs here
error[E0502]: cannot borrow `t` as immutable because it is also borrowed as mutable error[E0502]: cannot borrow `t` as immutable because it is also borrowed as mutable
--> $DIR/two-phase-nonrecv-autoref.rs:188:9 --> $DIR/two-phase-nonrecv-autoref.rs:184:9
| |
LL | t.m(t.i(10)); LL | t.m(t.i(10));
| - ^ - mutable borrow ends here | - ^ - mutable borrow ends here

View File

@ -7,17 +7,15 @@ LL | f(f(10));
| first mutable borrow occurs here | first mutable borrow occurs here
| first borrow later used by call | first borrow later used by call
error[E0382]: use of moved value: `*f` error[E0382]: use of moved value: `f`
--> $DIR/two-phase-nonrecv-autoref.rs:69:11 --> $DIR/two-phase-nonrecv-autoref.rs:69:11
| |
LL | fn twice_ten_so<F: FnOnce(i32) -> i32>(f: Box<F>) { LL | fn twice_ten_so<F: FnOnce(i32) -> i32>(f: Box<F>) {
| - consider adding a `Copy` constraint to this type argument | - move occurs because `f` has type `std::boxed::Box<F>`, which does not implement the `Copy` trait
LL | f(f(10)); LL | f(f(10));
| - ^ value used here after move | - ^ value used here after move
| | | |
| value moved here | value moved here
|
= note: move occurs because `*f` has type `F`, which does not implement the `Copy` trait
error[E0499]: cannot borrow `*f` as mutable more than once at a time error[E0499]: cannot borrow `*f` as mutable more than once at a time
--> $DIR/two-phase-nonrecv-autoref.rs:76:11 --> $DIR/two-phase-nonrecv-autoref.rs:76:11
@ -28,30 +26,18 @@ LL | f(f(10));
| first mutable borrow occurs here | first mutable borrow occurs here
| first borrow later used by call | first borrow later used by call
error[E0161]: cannot move a value of type dyn std::ops::FnOnce(i32) -> i32: the size of dyn std::ops::FnOnce(i32) -> i32 cannot be statically determined error[E0382]: use of moved value: `f`
--> $DIR/two-phase-nonrecv-autoref.rs:85:9
|
LL | f(f(10));
| ^
error[E0161]: cannot move a value of type dyn std::ops::FnOnce(i32) -> i32: the size of dyn std::ops::FnOnce(i32) -> i32 cannot be statically determined
--> $DIR/two-phase-nonrecv-autoref.rs:85:11
|
LL | f(f(10));
| ^
error[E0382]: use of moved value: `*f`
--> $DIR/two-phase-nonrecv-autoref.rs:85:11 --> $DIR/two-phase-nonrecv-autoref.rs:85:11
| |
LL | fn twice_ten_oo(f: Box<FnOnce(i32) -> i32>) {
| - move occurs because `f` has type `std::boxed::Box<dyn std::ops::FnOnce(i32) -> i32>`, which does not implement the `Copy` trait
LL | f(f(10)); LL | f(f(10));
| - ^ value used here after move | - ^ value used here after move
| | | |
| value moved here | value moved here
|
= note: move occurs because `*f` has type `dyn std::ops::FnOnce(i32) -> i32`, which does not implement the `Copy` trait
error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable
--> $DIR/two-phase-nonrecv-autoref.rs:129:27 --> $DIR/two-phase-nonrecv-autoref.rs:125:27
| |
LL | double_access(&mut a, &a); LL | double_access(&mut a, &a);
| ------------- ------ ^^ immutable borrow occurs here | ------------- ------ ^^ immutable borrow occurs here
@ -60,7 +46,7 @@ LL | double_access(&mut a, &a);
| mutable borrow later used by call | mutable borrow later used by call
error[E0502]: cannot borrow `i` as immutable because it is also borrowed as mutable error[E0502]: cannot borrow `i` as immutable because it is also borrowed as mutable
--> $DIR/two-phase-nonrecv-autoref.rs:157:7 --> $DIR/two-phase-nonrecv-autoref.rs:153:7
| |
LL | i[i[3]] = 4; LL | i[i[3]] = 4;
| --^---- | --^----
@ -70,7 +56,7 @@ LL | i[i[3]] = 4;
| mutable borrow later used here | mutable borrow later used here
error[E0502]: cannot borrow `i` as immutable because it is also borrowed as mutable error[E0502]: cannot borrow `i` as immutable because it is also borrowed as mutable
--> $DIR/two-phase-nonrecv-autoref.rs:163:7 --> $DIR/two-phase-nonrecv-autoref.rs:159:7
| |
LL | i[i[3]] = i[4]; LL | i[i[3]] = i[4];
| --^---- | --^----
@ -79,7 +65,7 @@ LL | i[i[3]] = i[4];
| mutable borrow occurs here | mutable borrow occurs here
| mutable borrow later used here | mutable borrow later used here
error: aborting due to 9 previous errors error: aborting due to 7 previous errors
Some errors occurred: E0161, E0382, E0499, E0502. Some errors occurred: E0382, E0499, E0502.
For more information about an error, try `rustc --explain E0161`. For more information about an error, try `rustc --explain E0382`.

View File

@ -67,9 +67,9 @@ fn overloaded_call_traits() {
} }
fn twice_ten_so<F: FnOnce(i32) -> i32>(f: Box<F>) { fn twice_ten_so<F: FnOnce(i32) -> i32>(f: Box<F>) {
f(f(10)); f(f(10));
//[nll]~^ ERROR use of moved value: `*f` //[nll]~^ ERROR use of moved value: `f`
//[g2p]~^^ ERROR use of moved value: `*f` //[g2p]~^^ ERROR use of moved value: `f`
//[ast]~^^^ ERROR use of moved value: `*f` //[ast]~^^^ ERROR use of moved value: `f`
} }
fn twice_ten_om(f: &mut FnMut(i32) -> i32) { fn twice_ten_om(f: &mut FnMut(i32) -> i32) {
@ -83,13 +83,9 @@ fn overloaded_call_traits() {
} }
fn twice_ten_oo(f: Box<FnOnce(i32) -> i32>) { fn twice_ten_oo(f: Box<FnOnce(i32) -> i32>) {
f(f(10)); f(f(10));
//[nll]~^ ERROR cannot move a value of type //[nll]~^ ERROR use of moved value: `f`
//[nll]~^^ ERROR cannot move a value of type //[g2p]~^^ ERROR use of moved value: `f`
//[nll]~^^^ ERROR use of moved value: `*f` //[ast]~^^^ ERROR use of moved value: `f`
//[g2p]~^^^^ ERROR cannot move a value of type
//[g2p]~^^^^^ ERROR cannot move a value of type
//[g2p]~^^^^^^ ERROR use of moved value: `*f`
//[ast]~^^^^^^^ ERROR use of moved value: `*f`
} }
twice_ten_sm(&mut |x| x + 1); twice_ten_sm(&mut |x| x + 1);

View File

@ -18,7 +18,7 @@ LL | fn test2<F>(f: &F) where F: FnMut() {
LL | (*f)(); LL | (*f)();
| ^^^^ `f` is a `&` reference, so the data it refers to cannot be borrowed as mutable | ^^^^ `f` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow `*f.f` as mutable, as it is behind a `&` reference error[E0596]: cannot borrow `f.f` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-call-is-borrow-issue-12224.rs:34:5 --> $DIR/borrowck-call-is-borrow-issue-12224.rs:34:5
| |
LL | fn test4(f: &Test) { LL | fn test4(f: &Test) {

View File

@ -32,7 +32,7 @@ fn test3<F>(f: &mut F) where F: FnMut() {
fn test4(f: &Test) { fn test4(f: &Test) {
f.f.call_mut(()) f.f.call_mut(())
//~^ ERROR: cannot borrow `Box` content `*f.f` of immutable binding as mutable //~^ ERROR: cannot borrow field `f.f` of immutable binding as mutable
} }
fn test5(f: &mut Test) { fn test5(f: &mut Test) {

View File

@ -19,13 +19,13 @@ LL | fn test2<F>(f: &F) where F: FnMut() {
LL | (*f)(); LL | (*f)();
| ^^^^ cannot borrow as mutable | ^^^^ cannot borrow as mutable
error[E0596]: cannot borrow `Box` content `*f.f` of immutable binding as mutable error[E0596]: cannot borrow field `f.f` of immutable binding as mutable
--> $DIR/borrowck-call-is-borrow-issue-12224.rs:34:5 --> $DIR/borrowck-call-is-borrow-issue-12224.rs:34:5
| |
LL | fn test4(f: &Test) { LL | fn test4(f: &Test) {
| ----- use `&mut Test` here to make mutable | ----- use `&mut Test` here to make mutable
LL | f.f.call_mut(()) LL | f.f.call_mut(())
| ^^^ cannot borrow as mutable | ^^^ cannot mutably borrow field of immutable binding
error[E0504]: cannot move `f` into closure because it is borrowed error[E0504]: cannot move `f` into closure because it is borrowed
--> $DIR/borrowck-call-is-borrow-issue-12224.rs:56:13 --> $DIR/borrowck-call-is-borrow-issue-12224.rs:56:13