Skip to content

Commit 4662b15

Browse files
committed
Auto merge of #41772 - GuillaumeGomez:fn-once-message, r=estebank
Add help message if a FnOnce is moved Fixes #40855. r? @eddyb
2 parents 5dfcd85 + 0c0d11b commit 4662b15

File tree

3 files changed

+60
-7
lines changed

3 files changed

+60
-7
lines changed

src/librustc_borrowck/borrowck/mod.rs

+24-7
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ use rustc::middle::free_region::RegionRelations;
3939
use rustc::ty::{self, TyCtxt};
4040
use rustc::ty::maps::Providers;
4141

42+
use syntax_pos::DUMMY_SP;
43+
4244
use std::fmt;
4345
use std::rc::Rc;
4446
use std::hash::{Hash, Hasher};
@@ -539,7 +541,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
539541
MovedInCapture => ("capture", "captured"),
540542
};
541543

542-
let (_ol, _moved_lp_msg, mut err) = match the_move.kind {
544+
let (_ol, _moved_lp_msg, mut err, need_note) = match the_move.kind {
543545
move_data::Declared => {
544546
// If this is an uninitialized variable, just emit a simple warning
545547
// and return.
@@ -586,11 +588,24 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
586588
let msg = if !has_fork && partial { "partially " }
587589
else if has_fork && !has_common { "collaterally "}
588590
else { "" };
589-
let err = struct_span_err!(
591+
let mut err = struct_span_err!(
590592
self.tcx.sess, use_span, E0382,
591593
"{} of {}moved value: `{}`",
592594
verb, msg, nl);
593-
(ol, moved_lp_msg, err)}
595+
let need_note = match lp.ty.sty {
596+
ty::TypeVariants::TyClosure(id, _) => {
597+
if let Ok(ty::ClosureKind::FnOnce) =
598+
ty::queries::closure_kind::try_get(self.tcx, DUMMY_SP, id) {
599+
err.help("closure was moved because it only implements `FnOnce`");
600+
false
601+
} else {
602+
true
603+
}
604+
}
605+
_ => true,
606+
};
607+
(ol, moved_lp_msg, err, need_note)
608+
}
594609
};
595610

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

630-
err.note(&format!("move occurs because `{}` has type `{}`, \
631-
which does not implement the `Copy` trait",
632-
self.loan_path_to_string(moved_lp),
633-
moved_lp.ty));
645+
if need_note {
646+
err.note(&format!("move occurs because `{}` has type `{}`, \
647+
which does not implement the `Copy` trait",
648+
self.loan_path_to_string(moved_lp),
649+
moved_lp.ty));
650+
}
634651

635652
// Note: we used to suggest adding a `ref binding` or calling
636653
// `clone` but those suggestions have been removed because

src/test/ui/fn_once-moved.rs

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use std::collections::HashMap;
12+
13+
fn main() {
14+
let dict: HashMap<i32, i32> = HashMap::new();
15+
let debug_dump_dict = || {
16+
for (key, value) in dict {
17+
println!("{:?} - {:?}", key, value);
18+
}
19+
};
20+
debug_dump_dict();
21+
debug_dump_dict();
22+
//~^ ERROR use of moved value: `debug_dump_dict`
23+
//~| NOTE closure was moved because it only implements `FnOnce`
24+
}

src/test/ui/fn_once-moved.stderr

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0382]: use of moved value: `debug_dump_dict`
2+
--> $DIR/fn_once-moved.rs:21:5
3+
|
4+
20 | debug_dump_dict();
5+
| --------------- value moved here
6+
21 | debug_dump_dict();
7+
| ^^^^^^^^^^^^^^^ value used here after move
8+
|
9+
= help: closure was moved because it only implements `FnOnce`
10+
11+
error: aborting due to previous error
12+

0 commit comments

Comments
 (0)