Skip to content

Commit

Permalink
Auto merge of #41772 - GuillaumeGomez:fn-once-message, r=estebank
Browse files Browse the repository at this point in the history
Add help message if a FnOnce is moved

Fixes #40855.

r? @eddyb
  • Loading branch information
bors committed May 19, 2017
2 parents 5dfcd85 + 0c0d11b commit 4662b15
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 7 deletions.
31 changes: 24 additions & 7 deletions src/librustc_borrowck/borrowck/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ use rustc::middle::free_region::RegionRelations;
use rustc::ty::{self, TyCtxt};
use rustc::ty::maps::Providers;

use syntax_pos::DUMMY_SP;

use std::fmt;
use std::rc::Rc;
use std::hash::{Hash, Hasher};
Expand Down Expand Up @@ -539,7 +541,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
MovedInCapture => ("capture", "captured"),
};

let (_ol, _moved_lp_msg, mut err) = match the_move.kind {
let (_ol, _moved_lp_msg, mut err, need_note) = match the_move.kind {
move_data::Declared => {
// If this is an uninitialized variable, just emit a simple warning
// and return.
Expand Down Expand Up @@ -586,11 +588,24 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
let msg = if !has_fork && partial { "partially " }
else if has_fork && !has_common { "collaterally "}
else { "" };
let err = struct_span_err!(
let mut err = struct_span_err!(
self.tcx.sess, use_span, E0382,
"{} of {}moved value: `{}`",
verb, msg, nl);
(ol, moved_lp_msg, err)}
let need_note = match lp.ty.sty {
ty::TypeVariants::TyClosure(id, _) => {
if let Ok(ty::ClosureKind::FnOnce) =
ty::queries::closure_kind::try_get(self.tcx, DUMMY_SP, id) {
err.help("closure was moved because it only implements `FnOnce`");
false
} else {
true
}
}
_ => true,
};
(ol, moved_lp_msg, err, need_note)
}
};

// Get type of value and span where it was previously
Expand Down Expand Up @@ -627,10 +642,12 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
err
};

err.note(&format!("move occurs because `{}` has type `{}`, \
which does not implement the `Copy` trait",
self.loan_path_to_string(moved_lp),
moved_lp.ty));
if need_note {
err.note(&format!("move occurs because `{}` has type `{}`, \
which does not implement the `Copy` trait",
self.loan_path_to_string(moved_lp),
moved_lp.ty));
}

// Note: we used to suggest adding a `ref binding` or calling
// `clone` but those suggestions have been removed because
Expand Down
24 changes: 24 additions & 0 deletions src/test/ui/fn_once-moved.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// 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.

use std::collections::HashMap;

fn main() {
let dict: HashMap<i32, i32> = HashMap::new();
let debug_dump_dict = || {
for (key, value) in dict {
println!("{:?} - {:?}", key, value);
}
};
debug_dump_dict();
debug_dump_dict();
//~^ ERROR use of moved value: `debug_dump_dict`
//~| NOTE closure was moved because it only implements `FnOnce`
}
12 changes: 12 additions & 0 deletions src/test/ui/fn_once-moved.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0382]: use of moved value: `debug_dump_dict`
--> $DIR/fn_once-moved.rs:21:5
|
20 | debug_dump_dict();
| --------------- value moved here
21 | debug_dump_dict();
| ^^^^^^^^^^^^^^^ value used here after move
|
= help: closure was moved because it only implements `FnOnce`

error: aborting due to previous error

0 comments on commit 4662b15

Please sign in to comment.