diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2025-08-07 21:09:42 +0000 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2025-08-10 19:22:49 +0000 |
| commit | 2484e189bfbc3decc2aa8480ce249dd84f6d2f9c (patch) | |
| tree | 3c1f98ed5903f07a6bdd09285e74be89a1534896 | |
| parent | 1aa5668d20d53976860d141a66aa727e425e1079 (diff) | |
| download | rust-2484e189bfbc3decc2aa8480ce249dd84f6d2f9c.tar.gz rust-2484e189bfbc3decc2aa8480ce249dd84f6d2f9c.zip | |
Add support for method calls
3 files changed, 725 insertions, 55 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index b24cb012d2b..5adbaca7e11 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -9,6 +9,7 @@ use rustc_middle::bug; use rustc_middle::mir::*; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_mir_dataflow::move_paths::{LookupResult, MovePathIndex}; +use rustc_span::def_id::DefId; use rustc_span::{BytePos, DUMMY_SP, ExpnKind, MacroKind, Span}; use rustc_trait_selection::error_reporting::traits::FindExprBySpan; use rustc_trait_selection::infer::InferCtxtExt; @@ -507,38 +508,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { ); let closure_span = tcx.def_span(def_id); - let mut clause_span = DUMMY_SP; - let typck_result = self.infcx.tcx.typeck(self.mir_def_id()); - if let Some(closure_def_id) = def_id.as_local() - && let hir::Node::Expr(expr) = tcx.hir_node_by_def_id(closure_def_id) - && let hir::Node::Expr(parent) = tcx.parent_hir_node(expr.hir_id) - && let hir::ExprKind::Call(callee, _) = parent.kind - && let Some(ty) = typck_result.node_type_opt(callee.hir_id) - && let ty::FnDef(fn_def_id, args) = ty.kind() - && let predicates = tcx.predicates_of(fn_def_id).instantiate(tcx, args) - && let Some((_, span)) = - predicates.predicates.iter().zip(predicates.spans.iter()).find( - |(pred, _)| match pred.as_trait_clause() { - Some(clause) - if let ty::Closure(clause_closure_def_id, _) = - clause.self_ty().skip_binder().kind() - && clause_closure_def_id == def_id - && (tcx.lang_items().fn_mut_trait() - == Some(clause.def_id()) - || tcx.lang_items().fn_trait() - == Some(clause.def_id())) => - { - // Found `<TyOfCapturingClosure as FnMut>` - true - } - _ => false, - }, - ) - { - // We point at the `Fn()` or `FnMut()` bound that coerced the closure, which - // could be changed to `FnOnce()` to avoid the move error. - clause_span = *span; - } self.cannot_move_out_of(span, &place_description) .with_span_label(upvar_span, "captured outer variable") @@ -547,7 +516,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { format!("captured by this `{closure_kind}` closure"), ) .with_span_help( - clause_span, + self.get_closure_bound_clause_span(*def_id), "`Fn` and `FnMut` closures require captured values to be able to be \ consumed multiple times, but an `FnOnce` consume them only once", ) @@ -599,6 +568,45 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { err } + fn get_closure_bound_clause_span(&self, def_id: DefId) -> Span { + let tcx = self.infcx.tcx; + let typeck_result = tcx.typeck(self.mir_def_id()); + let Some(closure_def_id) = def_id.as_local() else { return DUMMY_SP }; + let hir::Node::Expr(expr) = tcx.hir_node_by_def_id(closure_def_id) else { return DUMMY_SP }; + let hir::Node::Expr(parent) = tcx.parent_hir_node(expr.hir_id) else { return DUMMY_SP }; + let predicates = match parent.kind { + hir::ExprKind::Call(callee, _) => { + let Some(ty) = typeck_result.node_type_opt(callee.hir_id) else { return DUMMY_SP }; + let ty::FnDef(fn_def_id, args) = ty.kind() else { return DUMMY_SP }; + tcx.predicates_of(fn_def_id).instantiate(tcx, args) + } + hir::ExprKind::MethodCall(..) => { + let Some((_, method)) = typeck_result.type_dependent_def(parent.hir_id) else { + return DUMMY_SP; + }; + let args = typeck_result.node_args(parent.hir_id); + tcx.predicates_of(method).instantiate(tcx, args) + } + _ => return DUMMY_SP, + }; + for (pred, span) in predicates.predicates.iter().zip(predicates.spans.iter()) { + tracing::info!(?pred); + tracing::info!(?span); + if let Some(clause) = pred.as_trait_clause() + && let ty::Closure(clause_closure_def_id, _) = clause.self_ty().skip_binder().kind() + && *clause_closure_def_id == def_id + && (tcx.lang_items().fn_mut_trait() == Some(clause.def_id()) + || tcx.lang_items().fn_trait() == Some(clause.def_id())) + { + // Found `<TyOfCapturingClosure as FnMut>` + // We point at the `Fn()` or `FnMut()` bound that coerced the closure, which + // could be changed to `FnOnce()` to avoid the move error. + return *span; + } + } + DUMMY_SP + } + fn add_move_hints(&self, error: GroupedMoveError<'tcx>, err: &mut Diag<'_>, span: Span) { match error { GroupedMoveError::MovesFromPlace { mut binds_to, move_from, .. } => { diff --git a/tests/ui/suggestions/dont-suggest-ref/move-into-closure.rs b/tests/ui/suggestions/dont-suggest-ref/move-into-closure.rs index 0154810f564..34088f219b2 100644 --- a/tests/ui/suggestions/dont-suggest-ref/move-into-closure.rs +++ b/tests/ui/suggestions/dont-suggest-ref/move-into-closure.rs @@ -35,6 +35,32 @@ fn consume_fnmut<F: FnMut()>(_f: F) { } //~| HELP `Fn` and `FnMut` closures //~| HELP `Fn` and `FnMut` closures +trait T { + fn consume_fn<F: Fn()>(_f: F) { } + //~^ HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + fn method_consume_fn<F: Fn()>(&self, _f: F) { } + //~^ HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures +} +impl T for () {} + pub fn main() { } fn move_into_fn() { @@ -94,6 +120,120 @@ fn move_into_fn() { }); } +fn move_into_assoc_fn() { + let e = Either::One(X(Y)); + let mut em = Either::One(X(Y)); + + let x = X(Y); + + // move into Fn + + <() as T>::consume_fn(|| { + let X(_t) = x; + //~^ ERROR cannot move + //~| HELP consider borrowing here + if let Either::One(_t) = e { } + //~^ ERROR cannot move + //~| HELP consider borrowing here + while let Either::One(_t) = e { } + //~^ ERROR cannot move + //~| HELP consider borrowing here + match e { + //~^ ERROR cannot move + //~| HELP consider borrowing here + Either::One(_t) + | Either::Two(_t) => (), + } + match e { + //~^ ERROR cannot move + //~| HELP consider borrowing here + Either::One(_t) => (), + Either::Two(ref _t) => (), + // FIXME: should suggest removing `ref` too + } + + let X(mut _t) = x; + //~^ ERROR cannot move + //~| HELP consider borrowing here + if let Either::One(mut _t) = em { } + //~^ ERROR cannot move + //~| HELP consider borrowing here + while let Either::One(mut _t) = em { } + //~^ ERROR cannot move + //~| HELP consider borrowing here + match em { + //~^ ERROR cannot move + //~| HELP consider borrowing here + Either::One(mut _t) + | Either::Two(mut _t) => (), + } + match em { + //~^ ERROR cannot move + //~| HELP consider borrowing here + Either::One(mut _t) => (), + Either::Two(ref _t) => (), + // FIXME: should suggest removing `ref` too + } + }); +} + +fn move_into_method() { + let e = Either::One(X(Y)); + let mut em = Either::One(X(Y)); + + let x = X(Y); + + // move into Fn + + ().method_consume_fn(|| { + let X(_t) = x; + //~^ ERROR cannot move + //~| HELP consider borrowing here + if let Either::One(_t) = e { } + //~^ ERROR cannot move + //~| HELP consider borrowing here + while let Either::One(_t) = e { } + //~^ ERROR cannot move + //~| HELP consider borrowing here + match e { + //~^ ERROR cannot move + //~| HELP consider borrowing here + Either::One(_t) + | Either::Two(_t) => (), + } + match e { + //~^ ERROR cannot move + //~| HELP consider borrowing here + Either::One(_t) => (), + Either::Two(ref _t) => (), + // FIXME: should suggest removing `ref` too + } + + let X(mut _t) = x; + //~^ ERROR cannot move + //~| HELP consider borrowing here + if let Either::One(mut _t) = em { } + //~^ ERROR cannot move + //~| HELP consider borrowing here + while let Either::One(mut _t) = em { } + //~^ ERROR cannot move + //~| HELP consider borrowing here + match em { + //~^ ERROR cannot move + //~| HELP consider borrowing here + Either::One(mut _t) + | Either::Two(mut _t) => (), + } + match em { + //~^ ERROR cannot move + //~| HELP consider borrowing here + Either::One(mut _t) => (), + Either::Two(ref _t) => (), + // FIXME: should suggest removing `ref` too + } + }); +} + fn move_into_fnmut() { let e = Either::One(X(Y)); let mut em = Either::One(X(Y)); diff --git a/tests/ui/suggestions/dont-suggest-ref/move-into-closure.stderr b/tests/ui/suggestions/dont-suggest-ref/move-into-closure.stderr index d9ed25983d6..132a31c8f7c 100644 --- a/tests/ui/suggestions/dont-suggest-ref/move-into-closure.stderr +++ b/tests/ui/suggestions/dont-suggest-ref/move-into-closure.stderr @@ -1,5 +1,5 @@ error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:49:21 + --> $DIR/move-into-closure.rs:75:21 | LL | let x = X(Y); | - captured outer variable @@ -23,7 +23,7 @@ LL | let X(_t) = &x; | + error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:52:34 + --> $DIR/move-into-closure.rs:78:34 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -48,7 +48,7 @@ LL | if let Either::One(_t) = &e { } | + error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:55:37 + --> $DIR/move-into-closure.rs:81:37 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -73,7 +73,7 @@ LL | while let Either::One(_t) = &e { } | + error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:58:15 + --> $DIR/move-into-closure.rs:84:15 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -101,7 +101,7 @@ LL | match &e { | + error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:64:15 + --> $DIR/move-into-closure.rs:90:15 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -129,7 +129,7 @@ LL | match &e { | + error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:72:25 + --> $DIR/move-into-closure.rs:98:25 | LL | let x = X(Y); | - captured outer variable @@ -154,7 +154,7 @@ LL | let X(mut _t) = &x; | + error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:75:38 + --> $DIR/move-into-closure.rs:101:38 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -179,7 +179,7 @@ LL | if let Either::One(mut _t) = &em { } | + error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:78:41 + --> $DIR/move-into-closure.rs:104:41 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -204,7 +204,7 @@ LL | while let Either::One(mut _t) = &em { } | + error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:81:15 + --> $DIR/move-into-closure.rs:107:15 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -232,7 +232,7 @@ LL | match &em { | + error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:87:15 + --> $DIR/move-into-closure.rs:113:15 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -259,8 +259,530 @@ help: consider borrowing here LL | match &em { | + +error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:132:21 + | +LL | let x = X(Y); + | - captured outer variable +... +LL | <() as T>::consume_fn(|| { + | -- captured by this `Fn` closure +LL | let X(_t) = x; + | -- ^ + | | + | data moved here + | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:39:22 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | let X(_t) = &x; + | + + +error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:135:34 + | +LL | let e = Either::One(X(Y)); + | - captured outer variable +... +LL | <() as T>::consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | if let Either::One(_t) = e { } + | -- ^ + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:39:22 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | if let Either::One(_t) = &e { } + | + + +error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:138:37 + | +LL | let e = Either::One(X(Y)); + | - captured outer variable +... +LL | <() as T>::consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | while let Either::One(_t) = e { } + | -- ^ + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:39:22 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | while let Either::One(_t) = &e { } + | + + +error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:141:15 + | +LL | let e = Either::One(X(Y)); + | - captured outer variable +... +LL | <() as T>::consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | match e { + | ^ +... +LL | Either::One(_t) + | -- + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:39:22 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | match &e { + | + + +error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:147:15 + | +LL | let e = Either::One(X(Y)); + | - captured outer variable +... +LL | <() as T>::consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | match e { + | ^ +... +LL | Either::One(_t) => (), + | -- + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:39:22 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | match &e { + | + + +error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:155:25 + | +LL | let x = X(Y); + | - captured outer variable +... +LL | <() as T>::consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | let X(mut _t) = x; + | ------ ^ + | | + | data moved here + | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:39:22 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | let X(mut _t) = &x; + | + + +error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:158:38 + | +LL | let mut em = Either::One(X(Y)); + | ------ captured outer variable +... +LL | <() as T>::consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | if let Either::One(mut _t) = em { } + | ------ ^^ + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:39:22 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | if let Either::One(mut _t) = &em { } + | + + +error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:161:41 + | +LL | let mut em = Either::One(X(Y)); + | ------ captured outer variable +... +LL | <() as T>::consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | while let Either::One(mut _t) = em { } + | ------ ^^ + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:39:22 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | while let Either::One(mut _t) = &em { } + | + + +error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:164:15 + | +LL | let mut em = Either::One(X(Y)); + | ------ captured outer variable +... +LL | <() as T>::consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | match em { + | ^^ +... +LL | Either::One(mut _t) + | ------ + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:39:22 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | match &em { + | + + +error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:170:15 + | +LL | let mut em = Either::One(X(Y)); + | ------ captured outer variable +... +LL | <() as T>::consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | match em { + | ^^ +... +LL | Either::One(mut _t) => (), + | ------ + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:39:22 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | match &em { + | + + +error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:189:21 + | +LL | let x = X(Y); + | - captured outer variable +... +LL | ().method_consume_fn(|| { + | -- captured by this `Fn` closure +LL | let X(_t) = x; + | -- ^ + | | + | data moved here + | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:50:29 + | +LL | fn method_consume_fn<F: Fn()>(&self, _f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | let X(_t) = &x; + | + + +error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:192:34 + | +LL | let e = Either::One(X(Y)); + | - captured outer variable +... +LL | ().method_consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | if let Either::One(_t) = e { } + | -- ^ + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:50:29 + | +LL | fn method_consume_fn<F: Fn()>(&self, _f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | if let Either::One(_t) = &e { } + | + + +error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:195:37 + | +LL | let e = Either::One(X(Y)); + | - captured outer variable +... +LL | ().method_consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | while let Either::One(_t) = e { } + | -- ^ + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:50:29 + | +LL | fn method_consume_fn<F: Fn()>(&self, _f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | while let Either::One(_t) = &e { } + | + + +error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:198:15 + | +LL | let e = Either::One(X(Y)); + | - captured outer variable +... +LL | ().method_consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | match e { + | ^ +... +LL | Either::One(_t) + | -- + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:50:29 + | +LL | fn method_consume_fn<F: Fn()>(&self, _f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | match &e { + | + + +error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:204:15 + | +LL | let e = Either::One(X(Y)); + | - captured outer variable +... +LL | ().method_consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | match e { + | ^ +... +LL | Either::One(_t) => (), + | -- + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:50:29 + | +LL | fn method_consume_fn<F: Fn()>(&self, _f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | match &e { + | + + +error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:212:25 + | +LL | let x = X(Y); + | - captured outer variable +... +LL | ().method_consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | let X(mut _t) = x; + | ------ ^ + | | + | data moved here + | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:50:29 + | +LL | fn method_consume_fn<F: Fn()>(&self, _f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | let X(mut _t) = &x; + | + + +error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:215:38 + | +LL | let mut em = Either::One(X(Y)); + | ------ captured outer variable +... +LL | ().method_consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | if let Either::One(mut _t) = em { } + | ------ ^^ + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:50:29 + | +LL | fn method_consume_fn<F: Fn()>(&self, _f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | if let Either::One(mut _t) = &em { } + | + + +error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:218:41 + | +LL | let mut em = Either::One(X(Y)); + | ------ captured outer variable +... +LL | ().method_consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | while let Either::One(mut _t) = em { } + | ------ ^^ + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:50:29 + | +LL | fn method_consume_fn<F: Fn()>(&self, _f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | while let Either::One(mut _t) = &em { } + | + + +error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:221:15 + | +LL | let mut em = Either::One(X(Y)); + | ------ captured outer variable +... +LL | ().method_consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | match em { + | ^^ +... +LL | Either::One(mut _t) + | ------ + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:50:29 + | +LL | fn method_consume_fn<F: Fn()>(&self, _f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | match &em { + | + + +error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:227:15 + | +LL | let mut em = Either::One(X(Y)); + | ------ captured outer variable +... +LL | ().method_consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | match em { + | ^^ +... +LL | Either::One(mut _t) => (), + | ------ + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:50:29 + | +LL | fn method_consume_fn<F: Fn()>(&self, _f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | match &em { + | + + error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:106:21 + --> $DIR/move-into-closure.rs:246:21 | LL | let x = X(Y); | - captured outer variable @@ -284,7 +806,7 @@ LL | let X(_t) = &x; | + error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:109:34 + --> $DIR/move-into-closure.rs:249:34 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -309,7 +831,7 @@ LL | if let Either::One(_t) = &e { } | + error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:112:37 + --> $DIR/move-into-closure.rs:252:37 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -334,7 +856,7 @@ LL | while let Either::One(_t) = &e { } | + error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:115:15 + --> $DIR/move-into-closure.rs:255:15 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -362,7 +884,7 @@ LL | match &e { | + error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:121:15 + --> $DIR/move-into-closure.rs:261:15 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -390,7 +912,7 @@ LL | match &e { | + error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:129:25 + --> $DIR/move-into-closure.rs:269:25 | LL | let x = X(Y); | - captured outer variable @@ -415,7 +937,7 @@ LL | let X(mut _t) = &x; | + error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:132:38 + --> $DIR/move-into-closure.rs:272:38 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -440,7 +962,7 @@ LL | if let Either::One(mut _t) = &em { } | + error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:135:41 + --> $DIR/move-into-closure.rs:275:41 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -465,7 +987,7 @@ LL | while let Either::One(mut _t) = &em { } | + error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:138:15 + --> $DIR/move-into-closure.rs:278:15 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -493,7 +1015,7 @@ LL | match &em { | + error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:144:15 + --> $DIR/move-into-closure.rs:284:15 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -521,7 +1043,7 @@ LL | match &em { | + error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:151:15 + --> $DIR/move-into-closure.rs:291:15 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -548,6 +1070,6 @@ help: consider borrowing here LL | match &em { | + -error: aborting due to 21 previous errors +error: aborting due to 41 previous errors For more information about this error, try `rustc --explain E0507`. |
