diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 3b888940c2d..18d8bbf9047 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -380,61 +380,46 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let typeck = self.infcx.tcx.typeck(self.mir_def_id()); let hir_id = hir.get_parent_node(expr.hir_id); if let Some(parent) = hir.find(hir_id) { - if let hir::Node::Expr(parent_expr) = parent + let (def_id, args, offset) = if let hir::Node::Expr(parent_expr) = parent && let hir::ExprKind::MethodCall(_, _, args, _) = parent_expr.kind && let Some(def_id) = typeck.type_dependent_def_id(parent_expr.hir_id) - && let Some(def_id) = def_id.as_local() - && let Some(node) = hir.find(hir.local_def_id_to_hir_id(def_id)) - && let Some(fn_sig) = node.fn_sig() - && let Some(ident) = node.ident() - && let Some(pos) = args.iter() - .position(|arg| arg.hir_id == expr.hir_id) - && let Some(arg) = fn_sig.decl.inputs.get(pos + 1) { - let mut span: MultiSpan = arg.span.into(); - span.push_span_label( - arg.span, - "this type parameter takes ownership of the value".to_string(), - ); - span.push_span_label( - ident.span, - "in this method".to_string(), - ); - err.span_note( - span, - format!( - "consider changing this parameter type in `{}` to borrow instead \ - if ownering the value isn't necessary", - ident, - ), - ); - } - if let hir::Node::Expr(parent_expr) = parent + (def_id.as_local(), args, 1) + } else if let hir::Node::Expr(parent_expr) = parent && let hir::ExprKind::Call(call, args) = parent_expr.kind && let ty::FnDef(def_id, _) = typeck.node_type(call.hir_id).kind() - && let Some(def_id) = def_id.as_local() + { + (def_id.as_local(), args, 0) + } else { + (None, &[][..], 0) + }; + if let Some(def_id) = def_id && let Some(node) = hir.find(hir.local_def_id_to_hir_id(def_id)) && let Some(fn_sig) = node.fn_sig() && let Some(ident) = node.ident() && let Some(pos) = args.iter() .position(|arg| arg.hir_id == expr.hir_id) - && let Some(arg) = fn_sig.decl.inputs.get(pos) + && let Some(arg) = fn_sig.decl.inputs.get(pos + offset) { let mut span: MultiSpan = arg.span.into(); span.push_span_label( arg.span, "this type parameter takes ownership of the value".to_string(), ); + let descr = match node.fn_kind() { + Some(hir::intravisit::FnKind::ItemFn(..)) | None => "function", + Some(hir::intravisit::FnKind::Method(..)) => "method", + Some(hir::intravisit::FnKind::Closure) => "closure", + }; span.push_span_label( ident.span, - "in this function".to_string(), + format!("in this {descr}"), ); err.span_note( span, format!( - "consider changing this parameter type in `{}` to borrow instead \ - if ownering the value isn't necessary", - ident, + "consider changing this parameter type in {descr} `{ident}` to \ + borrow instead if ownering the value isn't necessary", ), ); } diff --git a/src/test/ui/borrowck/borrowck-consume-unsize-vec.stderr b/src/test/ui/borrowck/borrowck-consume-unsize-vec.stderr index 00bb13caebd..cfaa8c08df8 100644 --- a/src/test/ui/borrowck/borrowck-consume-unsize-vec.stderr +++ b/src/test/ui/borrowck/borrowck-consume-unsize-vec.stderr @@ -8,7 +8,7 @@ LL | consume(b); LL | consume(b); | ^ value used here after move | -note: consider changing this parameter type in `consume` to borrow instead if ownering the value isn't necessary +note: consider changing this parameter type in function `consume` to borrow instead if ownering the value isn't necessary --> $DIR/borrowck-consume-unsize-vec.rs:3:15 | LL | fn consume(_: Box<[i32]>) { diff --git a/src/test/ui/borrowck/borrowck-consume-upcast-box.stderr b/src/test/ui/borrowck/borrowck-consume-upcast-box.stderr index 103f45155d7..c73d1df971a 100644 --- a/src/test/ui/borrowck/borrowck-consume-upcast-box.stderr +++ b/src/test/ui/borrowck/borrowck-consume-upcast-box.stderr @@ -8,7 +8,7 @@ LL | consume(b); LL | consume(b); | ^ value used here after move | -note: consider changing this parameter type in `consume` to borrow instead if ownering the value isn't necessary +note: consider changing this parameter type in function `consume` to borrow instead if ownering the value isn't necessary --> $DIR/borrowck-consume-upcast-box.rs:5:15 | LL | fn consume(_: Box<dyn Foo>) { diff --git a/src/test/ui/borrowck/mut-borrow-in-loop-2.stderr b/src/test/ui/borrowck/mut-borrow-in-loop-2.stderr index eaf53868014..4f287d3a735 100644 --- a/src/test/ui/borrowck/mut-borrow-in-loop-2.stderr +++ b/src/test/ui/borrowck/mut-borrow-in-loop-2.stderr @@ -8,7 +8,7 @@ LL | for _ in 0..3 { LL | Other::handle(value); | ^^^^^ value moved here, in previous iteration of loop | -note: consider changing this parameter type in `handle` to borrow instead if ownering the value isn't necessary +note: consider changing this parameter type in function `handle` to borrow instead if ownering the value isn't necessary --> $DIR/mut-borrow-in-loop-2.rs:9:22 | LL | fn handle(value: T) -> Self; diff --git a/src/test/ui/liveness/liveness-move-call-arg.stderr b/src/test/ui/liveness/liveness-move-call-arg.stderr index bd45aa53458..4a869cdce4a 100644 --- a/src/test/ui/liveness/liveness-move-call-arg.stderr +++ b/src/test/ui/liveness/liveness-move-call-arg.stderr @@ -9,7 +9,7 @@ LL | loop { LL | take(x); | ^ value moved here, in previous iteration of loop | -note: consider changing this parameter type in `take` to borrow instead if ownering the value isn't necessary +note: consider changing this parameter type in function `take` to borrow instead if ownering the value isn't necessary --> $DIR/liveness-move-call-arg.rs:1:13 | LL | fn take(_x: Box<isize>) {} diff --git a/src/test/ui/liveness/liveness-use-after-send.stderr b/src/test/ui/liveness/liveness-use-after-send.stderr index c407827d320..cf4aa8fc9c4 100644 --- a/src/test/ui/liveness/liveness-use-after-send.stderr +++ b/src/test/ui/liveness/liveness-use-after-send.stderr @@ -8,7 +8,7 @@ LL | send(ch, message); LL | println!("{}", message); | ^^^^^^^ value borrowed here after move | -note: consider changing this parameter type in `send` to borrow instead if ownering the value isn't necessary +note: consider changing this parameter type in function `send` to borrow instead if ownering the value isn't necessary --> $DIR/liveness-use-after-send.rs:3:54 | LL | fn send<T:Send + std::fmt::Debug>(ch: Chan<T>, data: T) { diff --git a/src/test/ui/moves/borrow-closures-instead-of-move.stderr b/src/test/ui/moves/borrow-closures-instead-of-move.stderr index 11fcb1cc263..d3f250e69b2 100644 --- a/src/test/ui/moves/borrow-closures-instead-of-move.stderr +++ b/src/test/ui/moves/borrow-closures-instead-of-move.stderr @@ -8,7 +8,7 @@ LL | loop { LL | takes_fnonce(f); | ^ value moved here, in previous iteration of loop | -note: consider changing this parameter type in `takes_fnonce` to borrow instead if ownering the value isn't necessary +note: consider changing this parameter type in function `takes_fnonce` to borrow instead if ownering the value isn't necessary --> $DIR/borrow-closures-instead-of-move.rs:34:20 | LL | fn takes_fnonce(_: impl FnOnce()) {} @@ -32,7 +32,7 @@ LL | takes_fnonce(m); LL | takes_fnonce(m); | ^ value used here after move | -note: consider changing this parameter type in `takes_fnonce` to borrow instead if ownering the value isn't necessary +note: consider changing this parameter type in function `takes_fnonce` to borrow instead if ownering the value isn't necessary --> $DIR/borrow-closures-instead-of-move.rs:34:20 | LL | fn takes_fnonce(_: impl FnOnce()) {} @@ -58,7 +58,7 @@ note: closure cannot be moved more than once as it is not `Copy` due to moving t | LL | x += 1; | ^ -note: consider changing this parameter type in `takes_fnonce` to borrow instead if ownering the value isn't necessary +note: consider changing this parameter type in function `takes_fnonce` to borrow instead if ownering the value isn't necessary --> $DIR/borrow-closures-instead-of-move.rs:34:20 | LL | fn takes_fnonce(_: impl FnOnce()) {} diff --git a/src/test/ui/moves/move-guard-same-consts.stderr b/src/test/ui/moves/move-guard-same-consts.stderr index 04a41b9ce26..687e8497dc6 100644 --- a/src/test/ui/moves/move-guard-same-consts.stderr +++ b/src/test/ui/moves/move-guard-same-consts.stderr @@ -9,7 +9,7 @@ LL | (1, 2) if take(x) => (), LL | (1, 2) if take(x) => (), | ^ value used here after move | -note: consider changing this parameter type in `take` to borrow instead if ownering the value isn't necessary +note: consider changing this parameter type in function `take` to borrow instead if ownering the value isn't necessary --> $DIR/move-guard-same-consts.rs:25:15 | LL | fn take<T>(_: T) -> bool { false } diff --git a/src/test/ui/moves/move-in-guard-1.stderr b/src/test/ui/moves/move-in-guard-1.stderr index d435426f2ec..a21dca7f16e 100644 --- a/src/test/ui/moves/move-in-guard-1.stderr +++ b/src/test/ui/moves/move-in-guard-1.stderr @@ -9,7 +9,7 @@ LL | (1, _) if take(x) => (), LL | (_, 2) if take(x) => (), | ^ value used here after move | -note: consider changing this parameter type in `take` to borrow instead if ownering the value isn't necessary +note: consider changing this parameter type in function `take` to borrow instead if ownering the value isn't necessary --> $DIR/move-in-guard-1.rs:15:15 | LL | fn take<T>(_: T) -> bool { false } diff --git a/src/test/ui/moves/move-in-guard-2.stderr b/src/test/ui/moves/move-in-guard-2.stderr index 0f4895c2ac1..5277a812a44 100644 --- a/src/test/ui/moves/move-in-guard-2.stderr +++ b/src/test/ui/moves/move-in-guard-2.stderr @@ -7,7 +7,7 @@ LL | let x: Box<_> = Box::new(1); LL | (_, 2) if take(x) => (), | ^ value used here after move | -note: consider changing this parameter type in `take` to borrow instead if ownering the value isn't necessary +note: consider changing this parameter type in function `take` to borrow instead if ownering the value isn't necessary --> $DIR/move-in-guard-2.rs:13:15 | LL | fn take<T>(_: T) -> bool { false } diff --git a/src/test/ui/moves/moves-based-on-type-exprs.stderr b/src/test/ui/moves/moves-based-on-type-exprs.stderr index 78138d214f9..37fb40ffe78 100644 --- a/src/test/ui/moves/moves-based-on-type-exprs.stderr +++ b/src/test/ui/moves/moves-based-on-type-exprs.stderr @@ -108,7 +108,7 @@ LL | _ if guard(x) => 10, LL | touch(&x); | ^^ value borrowed here after move | -note: consider changing this parameter type in `guard` to borrow instead if ownering the value isn't necessary +note: consider changing this parameter type in function `guard` to borrow instead if ownering the value isn't necessary --> $DIR/moves-based-on-type-exprs.rs:6:14 | LL | fn guard(_s: String) -> bool {panic!()} diff --git a/src/test/ui/union/union-move.mirunsafeck.stderr b/src/test/ui/union/union-move.mirunsafeck.stderr index 91f2eaad944..46b7be440e0 100644 --- a/src/test/ui/union/union-move.mirunsafeck.stderr +++ b/src/test/ui/union/union-move.mirunsafeck.stderr @@ -9,7 +9,7 @@ LL | move_out(x.f1_nocopy); LL | move_out(x.f2_nocopy); | ^^^^^^^^^^^ value used here after move | -note: consider changing this parameter type in `move_out` to borrow instead if ownering the value isn't necessary +note: consider changing this parameter type in function `move_out` to borrow instead if ownering the value isn't necessary --> $DIR/union-move.rs:10:19 | LL | fn move_out<T>(x: T) {} @@ -28,7 +28,7 @@ LL | move_out(x.f2_nocopy); LL | move_out(x.f3_copy); | ^^^^^^^^^ value used here after move | -note: consider changing this parameter type in `move_out` to borrow instead if ownering the value isn't necessary +note: consider changing this parameter type in function `move_out` to borrow instead if ownering the value isn't necessary --> $DIR/union-move.rs:10:19 | LL | fn move_out<T>(x: T) {} diff --git a/src/test/ui/union/union-move.thirunsafeck.stderr b/src/test/ui/union/union-move.thirunsafeck.stderr index 91f2eaad944..46b7be440e0 100644 --- a/src/test/ui/union/union-move.thirunsafeck.stderr +++ b/src/test/ui/union/union-move.thirunsafeck.stderr @@ -9,7 +9,7 @@ LL | move_out(x.f1_nocopy); LL | move_out(x.f2_nocopy); | ^^^^^^^^^^^ value used here after move | -note: consider changing this parameter type in `move_out` to borrow instead if ownering the value isn't necessary +note: consider changing this parameter type in function `move_out` to borrow instead if ownering the value isn't necessary --> $DIR/union-move.rs:10:19 | LL | fn move_out<T>(x: T) {} @@ -28,7 +28,7 @@ LL | move_out(x.f2_nocopy); LL | move_out(x.f3_copy); | ^^^^^^^^^ value used here after move | -note: consider changing this parameter type in `move_out` to borrow instead if ownering the value isn't necessary +note: consider changing this parameter type in function `move_out` to borrow instead if ownering the value isn't necessary --> $DIR/union-move.rs:10:19 | LL | fn move_out<T>(x: T) {} diff --git a/src/test/ui/unsized-locals/borrow-after-move.stderr b/src/test/ui/unsized-locals/borrow-after-move.stderr index e6964a19842..f63684407ec 100644 --- a/src/test/ui/unsized-locals/borrow-after-move.stderr +++ b/src/test/ui/unsized-locals/borrow-after-move.stderr @@ -29,7 +29,7 @@ LL | drop_unsized(y); LL | println!("{}", &y); | ^^ value borrowed here after move | -note: consider changing this parameter type in `drop_unsized` to borrow instead if ownering the value isn't necessary +note: consider changing this parameter type in function `drop_unsized` to borrow instead if ownering the value isn't necessary --> $DIR/borrow-after-move.rs:14:31 | LL | fn drop_unsized<T: ?Sized>(_: T) {} diff --git a/src/test/ui/unsized-locals/double-move.stderr b/src/test/ui/unsized-locals/double-move.stderr index 7d7586b0a0b..b883067427f 100644 --- a/src/test/ui/unsized-locals/double-move.stderr +++ b/src/test/ui/unsized-locals/double-move.stderr @@ -17,7 +17,7 @@ LL | drop_unsized(y); LL | drop_unsized(y); | ^ value used here after move | -note: consider changing this parameter type in `drop_unsized` to borrow instead if ownering the value isn't necessary +note: consider changing this parameter type in function `drop_unsized` to borrow instead if ownering the value isn't necessary --> $DIR/double-move.rs:14:31 | LL | fn drop_unsized<T: ?Sized>(_: T) {} diff --git a/src/test/ui/use/use-after-move-implicity-coerced-object.stderr b/src/test/ui/use/use-after-move-implicity-coerced-object.stderr index a671434a303..7d94aa21682 100644 --- a/src/test/ui/use/use-after-move-implicity-coerced-object.stderr +++ b/src/test/ui/use/use-after-move-implicity-coerced-object.stderr @@ -10,7 +10,7 @@ LL | LL | let x = n.to_string(); | ^^^^^^^^^^^^^ value borrowed here after move | -note: consider changing this parameter type in `push` to borrow instead if ownering the value isn't necessary +note: consider changing this parameter type in method `push` to borrow instead if ownering the value isn't necessary --> $DIR/use-after-move-implicity-coerced-object.rs:17:27 | LL | fn push(&mut self, n: Box<dyn ToString + 'static>) {