Auto merge of #41772 - GuillaumeGomez:fn-once-message, r=estebank
Add help message if a FnOnce is moved Fixes #40855. r? @eddyb
This commit is contained in:
commit
4662b15be0
@ -39,6 +39,8 @@ use rustc::middle::free_region::RegionRelations;
|
|||||||
use rustc::ty::{self, TyCtxt};
|
use rustc::ty::{self, TyCtxt};
|
||||||
use rustc::ty::maps::Providers;
|
use rustc::ty::maps::Providers;
|
||||||
|
|
||||||
|
use syntax_pos::DUMMY_SP;
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
@ -539,7 +541,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
|||||||
MovedInCapture => ("capture", "captured"),
|
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 => {
|
move_data::Declared => {
|
||||||
// If this is an uninitialized variable, just emit a simple warning
|
// If this is an uninitialized variable, just emit a simple warning
|
||||||
// and return.
|
// and return.
|
||||||
@ -586,11 +588,24 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
|||||||
let msg = if !has_fork && partial { "partially " }
|
let msg = if !has_fork && partial { "partially " }
|
||||||
else if has_fork && !has_common { "collaterally "}
|
else if has_fork && !has_common { "collaterally "}
|
||||||
else { "" };
|
else { "" };
|
||||||
let err = struct_span_err!(
|
let mut err = struct_span_err!(
|
||||||
self.tcx.sess, use_span, E0382,
|
self.tcx.sess, use_span, E0382,
|
||||||
"{} of {}moved value: `{}`",
|
"{} of {}moved value: `{}`",
|
||||||
verb, msg, nl);
|
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
|
// Get type of value and span where it was previously
|
||||||
@ -627,10 +642,12 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
|||||||
err
|
err
|
||||||
};
|
};
|
||||||
|
|
||||||
err.note(&format!("move occurs because `{}` has type `{}`, \
|
if need_note {
|
||||||
which does not implement the `Copy` trait",
|
err.note(&format!("move occurs because `{}` has type `{}`, \
|
||||||
self.loan_path_to_string(moved_lp),
|
which does not implement the `Copy` trait",
|
||||||
moved_lp.ty));
|
self.loan_path_to_string(moved_lp),
|
||||||
|
moved_lp.ty));
|
||||||
|
}
|
||||||
|
|
||||||
// Note: we used to suggest adding a `ref binding` or calling
|
// Note: we used to suggest adding a `ref binding` or calling
|
||||||
// `clone` but those suggestions have been removed because
|
// `clone` but those suggestions have been removed because
|
||||||
|
24
src/test/ui/fn_once-moved.rs
Normal file
24
src/test/ui/fn_once-moved.rs
Normal file
@ -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
src/test/ui/fn_once-moved.stderr
Normal file
12
src/test/ui/fn_once-moved.stderr
Normal file
@ -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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user