Add specific message when moving from upvars in a non-FnOnce closure
This commit is contained in:
parent
341e5e3a61
commit
12412749ab
@ -11,6 +11,7 @@
|
||||
use rustc::hir;
|
||||
use rustc::mir::*;
|
||||
use rustc::ty;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use rustc_errors::DiagnosticBuilder;
|
||||
use syntax_pos::Span;
|
||||
|
||||
@ -230,14 +231,43 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
||||
IllegalMoveOriginKind::Static => {
|
||||
self.tcx.cannot_move_out_of(span, "static item", origin)
|
||||
}
|
||||
IllegalMoveOriginKind::BorrowedContent { target_ty: ty } => {
|
||||
IllegalMoveOriginKind::BorrowedContent { target_place: place } => {
|
||||
// Inspect the type of the content behind the
|
||||
// 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);
|
||||
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::Local(_) | Place::Static(_) => unreachable!(),
|
||||
}
|
||||
} =>
|
||||
{
|
||||
let closure_kind_ty =
|
||||
closure_substs.closure_kind_ty(def_id, self.tcx);
|
||||
let closure_kind = closure_kind_ty.to_opt_closure_kind();
|
||||
let place_description = match closure_kind {
|
||||
Some(ty::ClosureKind::Fn) => {
|
||||
"captured variable in an `Fn` closure"
|
||||
}
|
||||
Some(ty::ClosureKind::FnMut) => {
|
||||
"captured variable in an `FnMut` closure"
|
||||
}
|
||||
Some(ty::ClosureKind::FnOnce) => {
|
||||
bug!("closure kind does not match first argument type")
|
||||
}
|
||||
None => bug!("closure kind not inferred by borrowck"),
|
||||
};
|
||||
self.tcx.cannot_move_out_of(span, place_description, origin)
|
||||
}
|
||||
_ => self
|
||||
.tcx
|
||||
.cannot_move_out_of(span, "borrowed content", origin),
|
||||
|
@ -132,11 +132,11 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
|
||||
let mir = self.builder.mir;
|
||||
let tcx = self.builder.tcx;
|
||||
let place_ty = proj.base.ty(mir, tcx).to_ty(tcx);
|
||||
match place_ty.sty {
|
||||
match place_ty.sty {
|
||||
ty::TyRef(..) | ty::TyRawPtr(..) =>
|
||||
return Err(MoveError::cannot_move_out_of(
|
||||
self.loc,
|
||||
BorrowedContent { target_ty: place.ty(mir, tcx).to_ty(tcx) })),
|
||||
BorrowedContent { target_place: place.clone() })),
|
||||
ty::TyAdt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() =>
|
||||
return Err(MoveError::cannot_move_out_of(self.loc,
|
||||
InteriorOfTypeWithDestructor {
|
||||
|
@ -282,9 +282,9 @@ pub(crate) enum IllegalMoveOriginKind<'tcx> {
|
||||
|
||||
/// Illegal move due to attempt to move from behind a reference.
|
||||
BorrowedContent {
|
||||
/// The content's type: if erroneous code was trying to move
|
||||
/// from `*x` where `x: &T`, then this will be `T`.
|
||||
target_ty: ty::Ty<'tcx>,
|
||||
/// The place the reference refers to: if erroneous code was trying to
|
||||
/// move from `(*x).f` this will be `*x`.
|
||||
target_place: Place<'tcx>,
|
||||
},
|
||||
|
||||
/// Illegal move due to attempt to move from field of an ADT that
|
||||
|
@ -1,8 +1,8 @@
|
||||
error[E0507]: cannot move out of borrowed content
|
||||
error[E0507]: cannot move out of captured variable in an `Fn` closure
|
||||
--> $DIR/borrowck-in-static.rs:15:17
|
||||
|
|
||||
LL | Box::new(|| x) //~ ERROR cannot move out of captured outer variable
|
||||
| ^ cannot move out of borrowed content
|
||||
| ^ cannot move out of captured variable in an `Fn` closure
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
error[E0507]: cannot move out of borrowed content
|
||||
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 | y.into_iter();
|
||||
| ^ cannot move out of borrowed content
|
||||
| ^ cannot move out of captured variable in an `Fn` closure
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,16 +0,0 @@
|
||||
error[E0507]: cannot move out of borrowed content
|
||||
--> $DIR/E0161.rs:14:28
|
||||
|
|
||||
LL | let _x: Box<str> = box *"hello"; //~ ERROR E0161
|
||||
| ^^^^^^^^ cannot move out of borrowed content
|
||||
|
||||
error[E0161]: cannot move a value of type str: the size of str cannot be statically determined
|
||||
--> $DIR/E0161.rs:14:28
|
||||
|
|
||||
LL | let _x: Box<str> = box *"hello"; //~ ERROR E0161
|
||||
| ^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors occurred: E0161, E0507.
|
||||
For more information about an error, try `rustc --explain E0161`.
|
@ -1,8 +1,8 @@
|
||||
error[E0507]: cannot move out of borrowed content
|
||||
error[E0507]: cannot move out of captured variable in an `FnMut` closure
|
||||
--> $DIR/issue-4335.rs:16:20
|
||||
|
|
||||
LL | id(Box::new(|| *v))
|
||||
| ^^ cannot move out of borrowed content
|
||||
| ^^ cannot move out of captured variable in an `FnMut` closure
|
||||
|
||||
error[E0597]: `v` does not live long enough
|
||||
--> $DIR/issue-4335.rs:16:17
|
||||
|
@ -28,11 +28,11 @@ LL | fn test4(f: &Test) {
|
||||
LL | f.f.call_mut(())
|
||||
| ^^^ `f` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
||||
|
||||
error[E0507]: cannot move out of borrowed content
|
||||
error[E0507]: cannot move out of captured variable in an `FnMut` closure
|
||||
--> $DIR/borrowck-call-is-borrow-issue-12224.rs:66:13
|
||||
|
|
||||
LL | foo(f);
|
||||
| ^ cannot move out of borrowed content
|
||||
| ^ cannot move out of captured variable in an `FnMut` closure
|
||||
|
||||
error[E0505]: cannot move out of `f` because it is borrowed
|
||||
--> $DIR/borrowck-call-is-borrow-issue-12224.rs:65:16
|
||||
|
Loading…
Reference in New Issue
Block a user