Skip to content

Commit 372cb9b

Browse files
authoredJun 15, 2020
Rollup merge of #72389 - Aaron1011:feature/move-fn-self-msg, r=nikomatsakis
Explain move errors that occur due to method calls involving `self` When calling a method that takes `self` (e.g. `vec.into_iter()`), the method receiver is moved out of. If the method receiver is used again, a move error will be emitted:: ```rust fn main() { let a = vec![true]; a.into_iter(); a; } ``` emits ``` error[E0382]: use of moved value: `a` --> src/main.rs:4:5 | 2 | let a = vec![true]; | - move occurs because `a` has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait 3 | a.into_iter(); | - value moved here 4 | a; | ^ value used here after move ``` However, the error message doesn't make it clear that the move is caused by the call to `into_iter`. This PR adds additional messages to move errors when the move is caused by using a value as the receiver of a `self` method:: ``` error[E0382]: use of moved value: `a` --> vec.rs:4:5 | 2 | let a = vec![true]; | - move occurs because `a` has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait 3 | a.into_iter(); | ------------- value moved due to this method call 4 | a; | ^ value used here after move | note: this function takes `self`, which moves the receiver --> /home/aaron/repos/rust/src/libcore/iter/traits/collect.rs:239:5 | 239 | fn into_iter(self) -> Self::IntoIter; ``` TODO: - [x] Add special handling for `FnOnce/FnMut/Fn` - we probably don't want to point at the unstable trait methods - [x] Consider adding additional context for operations (e.g. `Shr::shr`) when the call was generated using the operator syntax (e.g. `a >> b`) - [x] Consider pointing to the method parent (impl or trait block) in addition to the method itself.
2 parents 5c61a8d + 4646e2d commit 372cb9b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+729
-103
lines changed
 

‎src/librustc_ast_lowering/expr.rs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_data_structures::thin_vec::ThinVec;
99
use rustc_errors::struct_span_err;
1010
use rustc_hir as hir;
1111
use rustc_hir::def::Res;
12-
use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned};
12+
use rustc_span::source_map::{respan, DesugaringKind, ForLoopLoc, Span, Spanned};
1313
use rustc_span::symbol::{sym, Ident, Symbol};
1414
use rustc_target::asm;
1515
use std::collections::hash_map::Entry;
@@ -25,6 +25,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
2525
}
2626

2727
pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
28+
let mut span = e.span;
2829
ensure_sufficient_stack(|| {
2930
let kind = match e.kind {
3031
ExprKind::Box(ref inner) => hir::ExprKind::Box(self.lower_expr(inner)),
@@ -53,6 +54,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
5354
hir::ExprKind::MethodCall(hir_seg, seg.ident.span, args, span)
5455
}
5556
ExprKind::Binary(binop, ref lhs, ref rhs) => {
57+
span = self.mark_span_with_reason(DesugaringKind::Operator, e.span, None);
5658
let binop = self.lower_binop(binop);
5759
let lhs = self.lower_expr(lhs);
5860
let rhs = self.lower_expr(rhs);
@@ -222,7 +224,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
222224
hir::Expr {
223225
hir_id: self.lower_node_id(e.id),
224226
kind,
225-
span: e.span,
227+
span,
226228
attrs: e.attrs.iter().map(|a| self.lower_attr(a)).collect::<Vec<_>>().into(),
227229
}
228230
})
@@ -237,6 +239,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
237239
}
238240

239241
fn lower_binop(&mut self, b: BinOp) -> hir::BinOp {
242+
let span = self.mark_span_with_reason(DesugaringKind::Operator, b.span, None);
240243
Spanned {
241244
node: match b.node {
242245
BinOpKind::Add => hir::BinOpKind::Add,
@@ -258,7 +261,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
258261
BinOpKind::Ge => hir::BinOpKind::Ge,
259262
BinOpKind::Gt => hir::BinOpKind::Gt,
260263
},
261-
span: b.span,
264+
span,
262265
}
263266
}
264267

@@ -1360,9 +1363,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
13601363
body: &Block,
13611364
opt_label: Option<Label>,
13621365
) -> hir::Expr<'hir> {
1366+
let orig_head_span = head.span;
13631367
// expand <head>
13641368
let mut head = self.lower_expr_mut(head);
1365-
let desugared_span = self.mark_span_with_reason(DesugaringKind::ForLoop, head.span, None);
1369+
let desugared_span = self.mark_span_with_reason(
1370+
DesugaringKind::ForLoop(ForLoopLoc::Head),
1371+
orig_head_span,
1372+
None,
1373+
);
13661374
head.span = desugared_span;
13671375

13681376
let iter = Ident::with_dummy_span(sym::iter);
@@ -1457,10 +1465,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
14571465
// `mut iter => { ... }`
14581466
let iter_arm = self.arm(iter_pat, loop_expr);
14591467

1468+
let into_iter_span = self.mark_span_with_reason(
1469+
DesugaringKind::ForLoop(ForLoopLoc::IntoIter),
1470+
orig_head_span,
1471+
None,
1472+
);
1473+
14601474
// `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
14611475
let into_iter_expr = {
14621476
let into_iter_path = &[sym::iter, sym::IntoIterator, sym::into_iter];
1463-
self.expr_call_std_path(desugared_span, into_iter_path, arena_vec![self; head])
1477+
self.expr_call_std_path(into_iter_span, into_iter_path, arena_vec![self; head])
14641478
};
14651479

14661480
let match_expr = self.arena.alloc(self.expr_match(

‎src/librustc_infer/infer/error_reporting/need_type_info.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
455455
let msg = if let Some(simple_ident) = pattern.simple_ident() {
456456
match pattern.span.desugaring_kind() {
457457
None => format!("consider giving `{}` {}", simple_ident, suffix),
458-
Some(DesugaringKind::ForLoop) => {
458+
Some(DesugaringKind::ForLoop(_)) => {
459459
"the element type for this iterator is not specified".to_string()
460460
}
461461
_ => format!("this needs {}", suffix),

0 commit comments

Comments
 (0)
Please sign in to comment.