Auto merge of #53164 - davidtwco:issue-52663-span-decl-captured-variables, r=nikomatsakis
Provide span for declaration of captured variables Part of #52663. r? @nikomatsakis
This commit is contained in:
commit
d679b57a3a
15 changed files with 153 additions and 63 deletions
|
@ -127,14 +127,14 @@ impl<'tcx> Place<'tcx> {
|
|||
/// of a closure type.
|
||||
pub fn is_upvar_field_projection<'cx, 'gcx>(&self, mir: &'cx Mir<'tcx>,
|
||||
tcx: &TyCtxt<'cx, 'gcx, 'tcx>) -> Option<Field> {
|
||||
let place = if let Place::Projection(ref proj) = self {
|
||||
let (place, by_ref) = if let Place::Projection(ref proj) = self {
|
||||
if let ProjectionElem::Deref = proj.elem {
|
||||
&proj.base
|
||||
(&proj.base, true)
|
||||
} else {
|
||||
self
|
||||
(self, false)
|
||||
}
|
||||
} else {
|
||||
self
|
||||
(self, false)
|
||||
};
|
||||
|
||||
match place {
|
||||
|
@ -142,14 +142,16 @@ impl<'tcx> Place<'tcx> {
|
|||
ProjectionElem::Field(field, _ty) => {
|
||||
let base_ty = proj.base.ty(mir, *tcx).to_ty(*tcx);
|
||||
|
||||
if base_ty.is_closure() || base_ty.is_generator() {
|
||||
if (base_ty.is_closure() || base_ty.is_generator()) &&
|
||||
(!by_ref || mir.upvar_decls[field.index()].by_ref)
|
||||
{
|
||||
Some(field)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
},
|
||||
_ => None,
|
||||
},
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -151,7 +151,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
|
|||
let location_table = &LocationTable::new(mir);
|
||||
|
||||
let mut errors_buffer = Vec::new();
|
||||
let (move_data, move_errors): (MoveData<'tcx>, Option<Vec<MoveError<'tcx>>>) =
|
||||
let (move_data, move_errors): (MoveData<'tcx>, Option<Vec<(Place<'tcx>, MoveError<'tcx>)>>) =
|
||||
match MoveData::gather_moves(mir, tcx) {
|
||||
Ok(move_data) => (move_data, None),
|
||||
Err((move_data, move_errors)) => (move_data, Some(move_errors)),
|
||||
|
|
|
@ -11,11 +11,12 @@
|
|||
use rustc::hir;
|
||||
use rustc::mir::*;
|
||||
use rustc::ty;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use rustc_errors::DiagnosticBuilder;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use borrow_check::MirBorrowckCtxt;
|
||||
use borrow_check::prefixes::PrefixSet;
|
||||
use dataflow::move_paths::{IllegalMoveOrigin, IllegalMoveOriginKind};
|
||||
use dataflow::move_paths::{LookupResult, MoveError, MovePathIndex};
|
||||
use util::borrowck_errors::{BorrowckErrors, Origin};
|
||||
|
@ -38,6 +39,7 @@ enum GroupedMoveError<'tcx> {
|
|||
// Match place can't be moved from
|
||||
// e.g. match x[0] { s => (), } where x: &[String]
|
||||
MovesFromMatchPlace {
|
||||
original_path: Place<'tcx>,
|
||||
span: Span,
|
||||
move_from: Place<'tcx>,
|
||||
kind: IllegalMoveOriginKind<'tcx>,
|
||||
|
@ -46,6 +48,7 @@ enum GroupedMoveError<'tcx> {
|
|||
// Part of a pattern can't be moved from,
|
||||
// e.g. match &String::new() { &x => (), }
|
||||
MovesFromPattern {
|
||||
original_path: Place<'tcx>,
|
||||
span: Span,
|
||||
move_from: MovePathIndex,
|
||||
kind: IllegalMoveOriginKind<'tcx>,
|
||||
|
@ -53,23 +56,27 @@ enum GroupedMoveError<'tcx> {
|
|||
},
|
||||
// Everything that isn't from pattern matching.
|
||||
OtherIllegalMove {
|
||||
original_path: Place<'tcx>,
|
||||
span: Span,
|
||||
kind: IllegalMoveOriginKind<'tcx>,
|
||||
},
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
||||
pub(crate) fn report_move_errors(&mut self, move_errors: Vec<MoveError<'tcx>>) {
|
||||
pub(crate) fn report_move_errors(&mut self, move_errors: Vec<(Place<'tcx>, MoveError<'tcx>)>) {
|
||||
let grouped_errors = self.group_move_errors(move_errors);
|
||||
for error in grouped_errors {
|
||||
self.report(error);
|
||||
}
|
||||
}
|
||||
|
||||
fn group_move_errors(&self, errors: Vec<MoveError<'tcx>>) -> Vec<GroupedMoveError<'tcx>> {
|
||||
fn group_move_errors(
|
||||
&self,
|
||||
errors: Vec<(Place<'tcx>, MoveError<'tcx>)>
|
||||
) -> Vec<GroupedMoveError<'tcx>> {
|
||||
let mut grouped_errors = Vec::new();
|
||||
for error in errors {
|
||||
self.append_to_grouped_errors(&mut grouped_errors, error);
|
||||
for (original_path, error) in errors {
|
||||
self.append_to_grouped_errors(&mut grouped_errors, original_path, error);
|
||||
}
|
||||
grouped_errors
|
||||
}
|
||||
|
@ -77,6 +84,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
fn append_to_grouped_errors(
|
||||
&self,
|
||||
grouped_errors: &mut Vec<GroupedMoveError<'tcx>>,
|
||||
original_path: Place<'tcx>,
|
||||
error: MoveError<'tcx>,
|
||||
) {
|
||||
match error {
|
||||
|
@ -116,6 +124,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
self.append_binding_error(
|
||||
grouped_errors,
|
||||
kind,
|
||||
original_path,
|
||||
move_from,
|
||||
*local,
|
||||
opt_match_place,
|
||||
|
@ -127,6 +136,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
grouped_errors.push(GroupedMoveError::OtherIllegalMove {
|
||||
span: stmt_source_info.span,
|
||||
original_path,
|
||||
kind,
|
||||
});
|
||||
}
|
||||
|
@ -137,6 +147,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
&self,
|
||||
grouped_errors: &mut Vec<GroupedMoveError<'tcx>>,
|
||||
kind: IllegalMoveOriginKind<'tcx>,
|
||||
original_path: Place<'tcx>,
|
||||
move_from: &Place<'tcx>,
|
||||
bind_to: Local,
|
||||
match_place: &Option<Place<'tcx>>,
|
||||
|
@ -176,6 +187,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
grouped_errors.push(GroupedMoveError::MovesFromMatchPlace {
|
||||
span,
|
||||
move_from: match_place.clone(),
|
||||
original_path,
|
||||
kind,
|
||||
binds_to,
|
||||
});
|
||||
|
@ -206,6 +218,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
grouped_errors.push(GroupedMoveError::MovesFromPattern {
|
||||
span: match_span,
|
||||
move_from: mpi,
|
||||
original_path,
|
||||
kind,
|
||||
binds_to: vec![bind_to],
|
||||
});
|
||||
|
@ -215,12 +228,23 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
|
||||
fn report(&mut self, error: GroupedMoveError<'tcx>) {
|
||||
let (mut err, err_span) = {
|
||||
let (span, kind): (Span, &IllegalMoveOriginKind) = match error {
|
||||
GroupedMoveError::MovesFromMatchPlace { span, ref kind, .. }
|
||||
| GroupedMoveError::MovesFromPattern { span, ref kind, .. }
|
||||
| GroupedMoveError::OtherIllegalMove { span, ref kind } => (span, kind),
|
||||
};
|
||||
let (span, original_path, kind): (Span, &Place<'tcx>, &IllegalMoveOriginKind) =
|
||||
match error {
|
||||
GroupedMoveError::MovesFromMatchPlace {
|
||||
span,
|
||||
ref original_path,
|
||||
ref kind,
|
||||
..
|
||||
} |
|
||||
GroupedMoveError::MovesFromPattern { span, ref original_path, ref kind, .. } |
|
||||
GroupedMoveError::OtherIllegalMove { span, ref original_path, ref kind } => {
|
||||
(span, original_path, kind)
|
||||
},
|
||||
};
|
||||
let origin = Origin::Mir;
|
||||
debug!("report: original_path={:?} span={:?}, kind={:?} \
|
||||
original_path.is_upvar_field_projection={:?}", original_path, span, kind,
|
||||
original_path.is_upvar_field_projection(self.mir, &self.tcx));
|
||||
(
|
||||
match kind {
|
||||
IllegalMoveOriginKind::Static => {
|
||||
|
@ -231,22 +255,17 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
// borrow to provide feedback about why this
|
||||
// was a move rather than a copy.
|
||||
let ty = place.ty(self.mir, self.tcx).to_ty(self.tcx);
|
||||
let is_upvar_field_projection =
|
||||
self.prefixes(&original_path, PrefixSet::All)
|
||||
.any(|p| p.is_upvar_field_projection(self.mir, &self.tcx)
|
||||
.is_some());
|
||||
match ty.sty {
|
||||
ty::TyArray(..) | ty::TySlice(..) => self
|
||||
.tcx
|
||||
.cannot_move_out_of_interior_noncopy(span, ty, None, origin),
|
||||
ty::TyClosure(def_id, closure_substs)
|
||||
if !self.mir.upvar_decls.is_empty()
|
||||
&& {
|
||||
match place {
|
||||
Place::Projection(ref proj) => {
|
||||
proj.base == Place::Local(Local::new(1))
|
||||
}
|
||||
Place::Promoted(_) |
|
||||
Place::Local(_) | Place::Static(_) => unreachable!(),
|
||||
}
|
||||
} =>
|
||||
{
|
||||
if !self.mir.upvar_decls.is_empty() && is_upvar_field_projection
|
||||
=> {
|
||||
let closure_kind_ty =
|
||||
closure_substs.closure_kind_ty(def_id, self.tcx);
|
||||
let closure_kind = closure_kind_ty.to_opt_closure_kind();
|
||||
|
@ -262,7 +281,28 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
None => bug!("closure kind not inferred by borrowck"),
|
||||
};
|
||||
self.tcx.cannot_move_out_of(span, place_description, origin)
|
||||
debug!("report: closure_kind_ty={:?} closure_kind={:?} \
|
||||
place_description={:?}", closure_kind_ty, closure_kind,
|
||||
place_description);
|
||||
|
||||
let mut diag = self.tcx.cannot_move_out_of(
|
||||
span, place_description, origin);
|
||||
|
||||
for prefix in self.prefixes(&original_path, PrefixSet::All) {
|
||||
if let Some(field) = prefix.is_upvar_field_projection(
|
||||
self.mir, &self.tcx) {
|
||||
let upvar_decl = &self.mir.upvar_decls[field.index()];
|
||||
let upvar_hir_id =
|
||||
upvar_decl.var_hir_id.assert_crate_local();
|
||||
let upvar_node_id =
|
||||
self.tcx.hir.hir_to_node_id(upvar_hir_id);
|
||||
let upvar_span = self.tcx.hir.span(upvar_node_id);
|
||||
diag.span_label(upvar_span, "captured outer variable");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
diag
|
||||
}
|
||||
_ => self
|
||||
.tcx
|
||||
|
|
|
@ -36,10 +36,18 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
error_access: AccessKind,
|
||||
location: Location,
|
||||
) {
|
||||
debug!(
|
||||
"report_mutability_error(\
|
||||
access_place={:?}, span={:?}, the_place_err={:?}, error_access={:?}, location={:?},\
|
||||
)",
|
||||
access_place, span, the_place_err, error_access, location,
|
||||
);
|
||||
|
||||
let mut err;
|
||||
let item_msg;
|
||||
let reason;
|
||||
let access_place_desc = self.describe_place(access_place);
|
||||
debug!("report_mutability_error: access_place_desc={:?}", access_place_desc);
|
||||
|
||||
match the_place_err {
|
||||
Place::Local(local) => {
|
||||
|
@ -63,7 +71,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
));
|
||||
|
||||
item_msg = format!("`{}`", access_place_desc.unwrap());
|
||||
if self.is_upvar(access_place) {
|
||||
if access_place.is_upvar_field_projection(self.mir, &self.tcx).is_some() {
|
||||
reason = ", as it is not declared as mutable".to_string();
|
||||
} else {
|
||||
let name = self.mir.upvar_decls[upvar_index.index()].debug_name;
|
||||
|
@ -82,7 +90,8 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
the_place_err.ty(self.mir, self.tcx).to_ty(self.tcx)
|
||||
));
|
||||
|
||||
reason = if self.is_upvar(access_place) {
|
||||
reason = if access_place.is_upvar_field_projection(self.mir,
|
||||
&self.tcx).is_some() {
|
||||
", as it is a captured variable in a `Fn` closure".to_string()
|
||||
} else {
|
||||
", as `Fn` closures cannot mutate their captured variables".to_string()
|
||||
|
@ -155,6 +164,8 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
}) => bug!("Unexpected immutable place."),
|
||||
}
|
||||
|
||||
debug!("report_mutability_error: item_msg={:?}, reason={:?}", item_msg, reason);
|
||||
|
||||
// `act` and `acted_on` are strings that let us abstract over
|
||||
// the verbs used in some diagnostic messages.
|
||||
let act;
|
||||
|
@ -199,6 +210,8 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
};
|
||||
|
||||
debug!("report_mutability_error: act={:?}, acted_on={:?}", act, acted_on);
|
||||
|
||||
match the_place_err {
|
||||
// We want to suggest users use `let mut` for local (user
|
||||
// variable) mutations...
|
||||
|
@ -382,31 +395,6 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
|
||||
err.buffer(&mut self.errors_buffer);
|
||||
}
|
||||
|
||||
// Does this place refer to what the user sees as an upvar
|
||||
fn is_upvar(&self, place: &Place<'tcx>) -> bool {
|
||||
match *place {
|
||||
Place::Projection(box Projection {
|
||||
ref base,
|
||||
elem: ProjectionElem::Field(_, _),
|
||||
}) => {
|
||||
let base_ty = base.ty(self.mir, self.tcx).to_ty(self.tcx);
|
||||
is_closure_or_generator(base_ty)
|
||||
}
|
||||
Place::Projection(box Projection {
|
||||
base:
|
||||
Place::Projection(box Projection {
|
||||
ref base,
|
||||
elem: ProjectionElem::Field(upvar_index, _),
|
||||
}),
|
||||
elem: ProjectionElem::Deref,
|
||||
}) => {
|
||||
let base_ty = base.ty(self.mir, self.tcx).to_ty(self.tcx);
|
||||
is_closure_or_generator(base_ty) && self.mir.upvar_decls[upvar_index.index()].by_ref
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn suggest_ampmut_self<'cx, 'gcx, 'tcx>(
|
||||
|
|
|
@ -27,7 +27,7 @@ struct MoveDataBuilder<'a, 'gcx: 'tcx, 'tcx: 'a> {
|
|||
mir: &'a Mir<'tcx>,
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
data: MoveData<'tcx>,
|
||||
errors: Vec<MoveError<'tcx>>,
|
||||
errors: Vec<(Place<'tcx>, MoveError<'tcx>)>,
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> MoveDataBuilder<'a, 'gcx, 'tcx> {
|
||||
|
@ -186,7 +186,9 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> MoveDataBuilder<'a, 'gcx, 'tcx> {
|
||||
fn finalize(self) -> Result<MoveData<'tcx>, (MoveData<'tcx>, Vec<MoveError<'tcx>>)> {
|
||||
fn finalize(
|
||||
self
|
||||
) -> Result<MoveData<'tcx>, (MoveData<'tcx>, Vec<(Place<'tcx>, MoveError<'tcx>)>)> {
|
||||
debug!("{}", {
|
||||
debug!("moves for {:?}:", self.mir.span);
|
||||
for (j, mo) in self.data.moves.iter_enumerated() {
|
||||
|
@ -207,9 +209,10 @@ impl<'a, 'gcx, 'tcx> MoveDataBuilder<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) fn gather_moves<'a, 'gcx, 'tcx>(mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>)
|
||||
-> Result<MoveData<'tcx>,
|
||||
(MoveData<'tcx>, Vec<MoveError<'tcx>>)> {
|
||||
pub(super) fn gather_moves<'a, 'gcx, 'tcx>(
|
||||
mir: &Mir<'tcx>,
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>
|
||||
) -> Result<MoveData<'tcx>, (MoveData<'tcx>, Vec<(Place<'tcx>, MoveError<'tcx>)>)> {
|
||||
let mut builder = MoveDataBuilder::new(mir, tcx);
|
||||
|
||||
builder.gather_args();
|
||||
|
@ -407,7 +410,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
|
|||
let path = match self.move_path_for(place) {
|
||||
Ok(path) | Err(MoveError::UnionMove { path }) => path,
|
||||
Err(error @ MoveError::IllegalMove { .. }) => {
|
||||
self.builder.errors.push(error);
|
||||
self.builder.errors.push((place.clone(), error));
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -313,7 +313,7 @@ impl<'tcx> MoveError<'tcx> {
|
|||
|
||||
impl<'a, 'gcx, 'tcx> MoveData<'tcx> {
|
||||
pub fn gather_moves(mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>)
|
||||
-> Result<Self, (Self, Vec<MoveError<'tcx>>)> {
|
||||
-> Result<Self, (Self, Vec<(Place<'tcx>, MoveError<'tcx>)>)> {
|
||||
builder::gather_moves(mir, tcx)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
error[E0507]: cannot move out of captured variable in an `Fn` closure
|
||||
--> $DIR/borrowck-in-static.rs:15:17
|
||||
|
|
||||
LL | let x = Box::new(0);
|
||||
| - captured outer variable
|
||||
LL | Box::new(|| x) //~ ERROR cannot move out of captured outer variable
|
||||
| ^ cannot move out of captured variable in an `Fn` closure
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
error[E0507]: cannot move out of captured variable in an `FnMut` closure
|
||||
--> $DIR/borrowck-move-by-capture.rs:19:29
|
||||
|
|
||||
LL | let bar: Box<_> = box 3;
|
||||
| --- captured outer variable
|
||||
LL | let _g = to_fn_mut(|| {
|
||||
LL | let _h = to_fn_once(move || -> isize { *bar }); //~ ERROR cannot move out of
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of captured variable in an `FnMut` closure
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
error[E0507]: cannot move out of captured variable in an `Fn` closure
|
||||
--> $DIR/unboxed-closures-move-upvar-from-non-once-ref-closure.rs:21:9
|
||||
|
|
||||
LL | let y = vec![format!("World")];
|
||||
| - captured outer variable
|
||||
LL | call(|| {
|
||||
LL | y.into_iter();
|
||||
| ^ cannot move out of captured variable in an `Fn` closure
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
error[E0507]: cannot move out of captured variable in an `FnMut` closure
|
||||
--> $DIR/issue-4335.rs:16:20
|
||||
|
|
||||
LL | fn f<'r, T>(v: &'r T) -> Box<FnMut() -> T + 'r> {
|
||||
| - captured outer variable
|
||||
LL | id(Box::new(|| *v))
|
||||
| ^^ cannot move out of captured variable in an `FnMut` closure
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
error[E0507]: cannot move out of captured variable in an `Fn` closure
|
||||
--> $DIR/moves-based-on-type-move-out-of-closure-env-issue-1965.rs:21:28
|
||||
|
|
||||
LL | let i = box 3;
|
||||
| - captured outer variable
|
||||
LL | let _f = to_fn(|| test(i)); //~ ERROR cannot move out
|
||||
| ^ cannot move out of captured variable in an `Fn` closure
|
||||
|
||||
|
|
23
src/test/ui/nll/issue-52663-span-decl-captured-variable.rs
Normal file
23
src/test/ui/nll/issue-52663-span-decl-captured-variable.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(nll)]
|
||||
|
||||
fn expect_fn<F>(f: F) where F : Fn() {
|
||||
f();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
{
|
||||
let x = (vec![22], vec![44]);
|
||||
expect_fn(|| drop(x.0));
|
||||
//~^ ERROR cannot move out of captured variable in an `Fn` closure [E0507]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
error[E0507]: cannot move out of captured variable in an `Fn` closure
|
||||
--> $DIR/issue-52663-span-decl-captured-variable.rs:20:26
|
||||
|
|
||||
LL | let x = (vec![22], vec![44]);
|
||||
| - captured outer variable
|
||||
LL | expect_fn(|| drop(x.0));
|
||||
| ^^^ cannot move out of captured variable in an `Fn` closure
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0507`.
|
|
@ -31,6 +31,9 @@ LL | f.f.call_mut(())
|
|||
error[E0507]: cannot move out of captured variable in an `FnMut` closure
|
||||
--> $DIR/borrowck-call-is-borrow-issue-12224.rs:66:13
|
||||
|
|
||||
LL | let mut f = move |g: Box<FnMut(isize)>, b: isize| {
|
||||
| ----- captured outer variable
|
||||
...
|
||||
LL | foo(f);
|
||||
| ^ cannot move out of captured variable in an `FnMut` closure
|
||||
|
||||
|
|
|
@ -1,24 +1,32 @@
|
|||
error[E0507]: cannot move out of captured variable in an `Fn` closure
|
||||
--> $DIR/unboxed-closure-illegal-move.rs:25:31
|
||||
|
|
||||
LL | let x = Box::new(0);
|
||||
| - captured outer variable
|
||||
LL | let f = to_fn(|| drop(x)); //~ ERROR cannot move
|
||||
| ^ cannot move out of captured variable in an `Fn` closure
|
||||
|
||||
error[E0507]: cannot move out of captured variable in an `FnMut` closure
|
||||
--> $DIR/unboxed-closure-illegal-move.rs:29:35
|
||||
|
|
||||
LL | let x = Box::new(0);
|
||||
| - captured outer variable
|
||||
LL | let f = to_fn_mut(|| drop(x)); //~ ERROR cannot move
|
||||
| ^ cannot move out of captured variable in an `FnMut` closure
|
||||
|
||||
error[E0507]: cannot move out of captured variable in an `Fn` closure
|
||||
--> $DIR/unboxed-closure-illegal-move.rs:38:36
|
||||
|
|
||||
LL | let x = Box::new(0);
|
||||
| - captured outer variable
|
||||
LL | let f = to_fn(move || drop(x)); //~ ERROR cannot move
|
||||
| ^ cannot move out of captured variable in an `Fn` closure
|
||||
|
||||
error[E0507]: cannot move out of captured variable in an `FnMut` closure
|
||||
--> $DIR/unboxed-closure-illegal-move.rs:42:40
|
||||
|
|
||||
LL | let x = Box::new(0);
|
||||
| - captured outer variable
|
||||
LL | let f = to_fn_mut(move || drop(x)); //~ ERROR cannot move
|
||||
| ^ cannot move out of captured variable in an `FnMut` closure
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue