Auto merge of #124136 - estebank:clone-o-rama-2, r=nnethercote

Provide more context and suggestions in borrowck errors involving closures

Start pointing to where bindings where declared when they are captured in closures:

```
error[E0597]: `x` does not live long enough
  --> $DIR/suggest-return-closure.rs:23:9
   |
LL |     let x = String::new();
   |         - binding `x` declared here
...
LL |     |c| {
   |     --- value captured here
LL |         x.push(c);
   |         ^ borrowed value does not live long enough
...
LL | }
   | -- borrow later used here
   | |
   | `x` dropped here while still borrowed
```

Suggest cloning in more cases involving closures:

```
error[E0507]: cannot move out of `foo` in pattern guard
  --> $DIR/issue-27282-move-ref-mut-into-guard.rs:11:19
   |
LL |             if { (|| { let mut bar = foo; bar.take() })(); false } => {},
   |                   ^^                 --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
   |                   |
   |                   `foo` is moved here
   |
   = note: variables bound in patterns cannot be moved from until after the end of the pattern guard
help: consider cloning the value if the performance cost is acceptable
   |
LL |             if { (|| { let mut bar = foo.clone(); bar.take() })(); false } => {},
   |                                         ++++++++
```

Mention when type parameter could be Clone

```
error[E0382]: use of moved value: `t`
  --> $DIR/use_of_moved_value_copy_suggestions.rs:7:9
   |
LL | fn duplicate_t<T>(t: T) -> (T, T) {
   |                   - move occurs because `t` has type `T`, which does not implement the `Copy` trait
...
LL |     (t, t)
   |      -  ^ value used here after move
   |      |
   |      value moved here
   |
help: if `T` implemented `Clone`, you could clone the value
  --> $DIR/use_of_moved_value_copy_suggestions.rs:4:16
   |
LL | fn duplicate_t<T>(t: T) -> (T, T) {
   |                ^ consider constraining this type parameter with `Clone`
...
LL |     (t, t)
   |      - you could clone this value
help: consider restricting type parameter `T`
   |
LL | fn duplicate_t<T: Copy>(t: T) -> (T, T) {
   |                 ++++++
```

The `help` is new. On ADTs, we also extend the output with span labels:

```
error[E0507]: cannot move out of static item `FOO`
  --> $DIR/issue-17718-static-move.rs:6:14
   |
LL |     let _a = FOO;
   |              ^^^ move occurs because `FOO` has type `Foo`, which does not implement the `Copy` trait
   |
note: if `Foo` implemented `Clone`, you could clone the value
  --> $DIR/issue-17718-static-move.rs:1:1
   |
LL | struct Foo;
   | ^^^^^^^^^^ consider implementing `Clone` for this type
...
LL |     let _a = FOO;
   |              --- you could clone this value
help: consider borrowing here
   |
LL |     let _a = &FOO;
   |              +
```

Suggest cloning captured binding in move closure

```
error[E0507]: cannot move out of `bar`, a captured variable in an `FnMut` closure
  --> $DIR/borrowck-move-by-capture.rs:9:29
   |
LL |     let bar: Box<_> = Box::new(3);
   |         --- captured outer variable
LL |     let _g = to_fn_mut(|| {
   |                        -- captured by this `FnMut` closure
LL |         let _h = to_fn_once(move || -> isize { *bar });
   |                             ^^^^^^^^^^^^^^^^   ----
   |                             |                  |
   |                             |                  variable moved due to use in closure
   |                             |                  move occurs because `bar` has type `Box<isize>`, which does not implement the `Copy` trait
   |                             `bar` is moved here
   |
help: clone the value before moving it into the closure 1
   |
LL ~         let value = bar.clone();
LL ~         let _h = to_fn_once(move || -> isize { value });
   |
```
This commit is contained in:
bors 2024-04-25 01:00:41 +00:00
commit cb3752d20e
84 changed files with 1098 additions and 128 deletions

View File

@ -347,7 +347,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
mpi: MovePathIndex,
err: &mut Diag<'tcx>,
in_pattern: &mut bool,
move_spans: UseSpans<'_>,
move_spans: UseSpans<'tcx>,
) {
let move_span = match move_spans {
UseSpans::ClosureUse { capture_kind_span, .. } => capture_kind_span,
@ -491,11 +491,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
..
} = move_spans
{
self.suggest_cloning(err, ty, expr, None);
self.suggest_cloning(err, ty, expr, None, Some(move_spans));
} else if self.suggest_hoisting_call_outside_loop(err, expr) {
// The place where the the type moves would be misleading to suggest clone.
// #121466
self.suggest_cloning(err, ty, expr, None);
self.suggest_cloning(err, ty, expr, None, Some(move_spans));
}
}
if let Some(pat) = finder.pat {
@ -1085,6 +1085,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
ty: Ty<'tcx>,
mut expr: &'cx hir::Expr<'cx>,
mut other_expr: Option<&'cx hir::Expr<'cx>>,
use_spans: Option<UseSpans<'tcx>>,
) {
if let hir::ExprKind::Struct(_, _, Some(_)) = expr.kind {
// We have `S { foo: val, ..base }`. In `check_aggregate_rvalue` we have a single
@ -1197,14 +1198,50 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
.all(|field| self.implements_clone(field.ty(self.infcx.tcx, args)))
})
{
let ty_span = self.infcx.tcx.def_span(def.did());
let mut span: MultiSpan = ty_span.into();
span.push_span_label(ty_span, "consider implementing `Clone` for this type");
span.push_span_label(expr.span, "you could clone this value");
err.span_note(
self.infcx.tcx.def_span(def.did()),
span,
format!("if `{ty}` implemented `Clone`, you could clone the value"),
);
} else if let ty::Param(param) = ty.kind()
&& let Some(_clone_trait_def) = self.infcx.tcx.lang_items().clone_trait()
&& let generics = self.infcx.tcx.generics_of(self.mir_def_id())
&& let generic_param = generics.type_param(*param, self.infcx.tcx)
&& let param_span = self.infcx.tcx.def_span(generic_param.def_id)
&& if let Some(UseSpans::FnSelfUse { kind, .. }) = use_spans
&& let CallKind::FnCall { fn_trait_id, self_ty } = kind
&& let ty::Param(_) = self_ty.kind()
&& ty == self_ty
&& [
self.infcx.tcx.lang_items().fn_once_trait(),
self.infcx.tcx.lang_items().fn_mut_trait(),
self.infcx.tcx.lang_items().fn_trait(),
]
.contains(&Some(fn_trait_id))
{
// Do not suggest `F: FnOnce() + Clone`.
false
} else {
true
}
{
let mut span: MultiSpan = param_span.into();
span.push_span_label(
param_span,
"consider constraining this type parameter with `Clone`",
);
span.push_span_label(expr.span, "you could clone this value");
err.span_help(
span,
format!("if `{ty}` implemented `Clone`, you could clone the value"),
);
}
}
fn implements_clone(&self, ty: Ty<'tcx>) -> bool {
pub(crate) fn implements_clone(&self, ty: Ty<'tcx>) -> bool {
let Some(clone_trait_def) = self.infcx.tcx.lang_items().clone_trait() else { return false };
self.infcx
.type_implements_trait(clone_trait_def, [ty], self.param_env)
@ -1403,7 +1440,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if let Some(expr) = self.find_expr(borrow_span)
&& let Some(ty) = typeck_results.node_type_opt(expr.hir_id)
{
self.suggest_cloning(&mut err, ty, expr, self.find_expr(span));
self.suggest_cloning(&mut err, ty, expr, self.find_expr(span), Some(move_spans));
}
self.buffer_error(err);
}
@ -1964,7 +2001,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
pub(crate) fn find_expr(&self, span: Span) -> Option<&hir::Expr<'_>> {
let tcx = self.infcx.tcx;
let body_id = tcx.hir_node(self.mir_hir_id()).body_id()?;
let mut expr_finder = FindExprBySpan::new(span);
let mut expr_finder = FindExprBySpan::new(span, tcx);
expr_finder.visit_expr(tcx.hir().body(body_id).value);
expr_finder.result
}
@ -1998,14 +2035,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
};
let mut expr_finder =
FindExprBySpan::new(self.body.local_decls[*index1].source_info.span);
FindExprBySpan::new(self.body.local_decls[*index1].source_info.span, tcx);
expr_finder.visit_expr(hir.body(body_id).value);
let Some(index1) = expr_finder.result else {
note_default_suggestion();
return;
};
expr_finder = FindExprBySpan::new(self.body.local_decls[*index2].source_info.span);
expr_finder = FindExprBySpan::new(self.body.local_decls[*index2].source_info.span, tcx);
expr_finder.visit_expr(hir.body(body_id).value);
let Some(index2) = expr_finder.result else {
note_default_suggestion();

View File

@ -76,7 +76,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
&& let Some(body_id) = node.body_id()
{
let body = tcx.hir().body(body_id);
let mut expr_finder = FindExprBySpan::new(span);
let mut expr_finder = FindExprBySpan::new(span, tcx);
expr_finder.visit_expr(body.value);
if let Some(mut expr) = expr_finder.result {
while let hir::ExprKind::AddrOf(_, _, inner)

View File

@ -2,10 +2,13 @@
#![allow(rustc::untranslatable_diagnostic)]
use rustc_errors::{Applicability, Diag};
use rustc_hir::intravisit::Visitor;
use rustc_hir::{CaptureBy, ExprKind, HirId, Node};
use rustc_middle::mir::*;
use rustc_middle::ty::{self, Ty};
use rustc_mir_dataflow::move_paths::{LookupResult, MovePathIndex};
use rustc_span::{BytePos, ExpnKind, MacroKind, Span};
use rustc_trait_selection::traits::error_reporting::FindExprBySpan;
use crate::diagnostics::CapturedMessageOpt;
use crate::diagnostics::{DescribePlaceOpt, UseSpans};
@ -303,6 +306,121 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
self.cannot_move_out_of(span, &description)
}
fn suggest_clone_of_captured_var_in_move_closure(
&self,
err: &mut Diag<'_>,
upvar_hir_id: HirId,
upvar_name: &str,
use_spans: Option<UseSpans<'tcx>>,
) {
let tcx = self.infcx.tcx;
let typeck_results = tcx.typeck(self.mir_def_id());
let Some(use_spans) = use_spans else { return };
// We only care about the case where a closure captured a binding.
let UseSpans::ClosureUse { args_span, .. } = use_spans else { return };
let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else { return };
// Fetch the type of the expression corresponding to the closure-captured binding.
let Some(captured_ty) = typeck_results.node_type_opt(upvar_hir_id) else { return };
if !self.implements_clone(captured_ty) {
// We only suggest cloning the captured binding if the type can actually be cloned.
return;
};
// Find the closure that captured the binding.
let mut expr_finder = FindExprBySpan::new(args_span, tcx);
expr_finder.include_closures = true;
expr_finder.visit_expr(tcx.hir().body(body_id).value);
let Some(closure_expr) = expr_finder.result else { return };
let ExprKind::Closure(closure) = closure_expr.kind else { return };
// We'll only suggest cloning the binding if it's a `move` closure.
let CaptureBy::Value { .. } = closure.capture_clause else { return };
// Find the expression within the closure where the binding is consumed.
let mut suggested = false;
let use_span = use_spans.var_or_use();
let mut expr_finder = FindExprBySpan::new(use_span, tcx);
expr_finder.include_closures = true;
expr_finder.visit_expr(tcx.hir().body(body_id).value);
let Some(use_expr) = expr_finder.result else { return };
let parent = tcx.parent_hir_node(use_expr.hir_id);
if let Node::Expr(expr) = parent
&& let ExprKind::Assign(lhs, ..) = expr.kind
&& lhs.hir_id == use_expr.hir_id
{
// Cloning the value being assigned makes no sense:
//
// error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure
// --> $DIR/option-content-move2.rs:11:9
// |
// LL | let mut var = None;
// | ------- captured outer variable
// LL | func(|| {
// | -- captured by this `FnMut` closure
// LL | // Shouldn't suggest `move ||.as_ref()` here
// LL | move || {
// | ^^^^^^^ `var` is moved here
// LL |
// LL | var = Some(NotCopyable);
// | ---
// | |
// | variable moved due to use in closure
// | move occurs because `var` has type `Option<NotCopyable>`, which does not implement the `Copy` trait
// |
return;
}
// Search for an appropriate place for the structured `.clone()` suggestion to be applied.
// If we encounter a statement before the borrow error, we insert a statement there.
for (_, node) in tcx.hir().parent_iter(closure_expr.hir_id) {
if let Node::Stmt(stmt) = node {
let padding = tcx
.sess
.source_map()
.indentation_before(stmt.span)
.unwrap_or_else(|| " ".to_string());
err.multipart_suggestion_verbose(
"clone the value before moving it into the closure",
vec![
(
stmt.span.shrink_to_lo(),
format!("let value = {upvar_name}.clone();\n{padding}"),
),
(use_span, "value".to_string()),
],
Applicability::MachineApplicable,
);
suggested = true;
break;
} else if let Node::Expr(expr) = node
&& let ExprKind::Closure(_) = expr.kind
{
// We want to suggest cloning only on the first closure, not
// subsequent ones (like `ui/suggestions/option-content-move2.rs`).
break;
}
}
if !suggested {
// If we couldn't find a statement for us to insert a new `.clone()` statement before,
// we have a bare expression, so we suggest the creation of a new block inline to go
// from `move || val` to `{ let value = val.clone(); move || value }`.
let padding = tcx
.sess
.source_map()
.indentation_before(closure_expr.span)
.unwrap_or_else(|| " ".to_string());
err.multipart_suggestion_verbose(
"clone the value before moving it into the closure",
vec![
(
closure_expr.span.shrink_to_lo(),
format!("{{\n{padding}let value = {upvar_name}.clone();\n{padding}"),
),
(use_spans.var_or_use(), "value".to_string()),
(closure_expr.span.shrink_to_hi(), format!("\n{padding}}}")),
],
Applicability::MachineApplicable,
);
}
}
fn report_cannot_move_from_borrowed_content(
&mut self,
move_place: Place<'tcx>,
@ -310,10 +428,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
span: Span,
use_spans: Option<UseSpans<'tcx>>,
) -> Diag<'tcx> {
let tcx = self.infcx.tcx;
// Inspect the type of the content behind the
// borrow to provide feedback about why this
// was a move rather than a copy.
let ty = deref_target_place.ty(self.body, self.infcx.tcx).ty;
let ty = deref_target_place.ty(self.body, tcx).ty;
let upvar_field = self
.prefixes(move_place.as_ref(), PrefixSet::All)
.find_map(|p| self.is_upvar_field_projection(p));
@ -363,8 +482,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let upvar = &self.upvars[upvar_field.unwrap().index()];
let upvar_hir_id = upvar.get_root_variable();
let upvar_name = upvar.to_string(self.infcx.tcx);
let upvar_span = self.infcx.tcx.hir().span(upvar_hir_id);
let upvar_name = upvar.to_string(tcx);
let upvar_span = tcx.hir().span(upvar_hir_id);
let place_name = self.describe_any_place(move_place.as_ref());
@ -380,12 +499,21 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
closure_kind_ty, closure_kind, place_description,
);
self.cannot_move_out_of(span, &place_description)
let closure_span = tcx.def_span(def_id);
let mut err = self
.cannot_move_out_of(span, &place_description)
.with_span_label(upvar_span, "captured outer variable")
.with_span_label(
self.infcx.tcx.def_span(def_id),
closure_span,
format!("captured by this `{closure_kind}` closure"),
)
);
self.suggest_clone_of_captured_var_in_move_closure(
&mut err,
upvar_hir_id,
&upvar_name,
use_spans,
);
err
}
_ => {
let source = self.borrowed_content_source(deref_base);
@ -415,7 +543,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
),
(_, _, _) => self.cannot_move_out_of(
span,
&source.describe_for_unnamed_place(self.infcx.tcx),
&source.describe_for_unnamed_place(tcx),
),
}
}
@ -447,7 +575,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
};
if let Some(expr) = self.find_expr(span) {
self.suggest_cloning(err, place_ty, expr, self.find_expr(other_span));
self.suggest_cloning(err, place_ty, expr, self.find_expr(other_span), None);
}
err.subdiagnostic(
@ -482,7 +610,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
};
if let Some(expr) = self.find_expr(use_span) {
self.suggest_cloning(err, place_ty, expr, self.find_expr(span));
self.suggest_cloning(
err,
place_ty,
expr,
self.find_expr(span),
Some(use_spans),
);
}
err.subdiagnostic(
@ -595,7 +729,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let place_desc = &format!("`{}`", self.local_names[*local].unwrap());
if let Some(expr) = self.find_expr(binding_span) {
self.suggest_cloning(err, bind_to.ty, expr, None);
self.suggest_cloning(err, bind_to.ty, expr, None, None);
}
err.subdiagnostic(

View File

@ -50,22 +50,38 @@ pub struct FindExprBySpan<'hir> {
pub span: Span,
pub result: Option<&'hir hir::Expr<'hir>>,
pub ty_result: Option<&'hir hir::Ty<'hir>>,
pub include_closures: bool,
pub tcx: TyCtxt<'hir>,
}
impl<'hir> FindExprBySpan<'hir> {
pub fn new(span: Span) -> Self {
Self { span, result: None, ty_result: None }
pub fn new(span: Span, tcx: TyCtxt<'hir>) -> Self {
Self { span, result: None, ty_result: None, tcx, include_closures: false }
}
}
impl<'v> Visitor<'v> for FindExprBySpan<'v> {
type NestedFilter = rustc_middle::hir::nested_filter::OnlyBodies;
fn nested_visit_map(&mut self) -> Self::Map {
self.tcx.hir()
}
fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
if self.span == ex.span {
self.result = Some(ex);
} else {
if let hir::ExprKind::Closure(..) = ex.kind
&& self.include_closures
&& let closure_header_sp = self.span.with_hi(ex.span.hi())
&& closure_header_sp == ex.span
{
self.result = Some(ex);
}
hir::intravisit::walk_expr(self, ex);
}
}
fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
if self.span == ty.span {
self.ty_result = Some(ty);

View File

@ -901,7 +901,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// Remove all the desugaring and macro contexts.
span.remove_mark();
}
let mut expr_finder = FindExprBySpan::new(span);
let mut expr_finder = FindExprBySpan::new(span, self.tcx);
let Some(body_id) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) else {
return;
};
@ -1367,7 +1367,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
return false;
};
let body = self.tcx.hir().body(body_id);
let mut expr_finder = FindExprBySpan::new(span);
let mut expr_finder = FindExprBySpan::new(span, self.tcx);
expr_finder.visit_expr(body.value);
let Some(expr) = expr_finder.result else {
return false;
@ -1469,7 +1469,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// Remove all the hir desugaring contexts while maintaining the macro contexts.
span.remove_mark();
}
let mut expr_finder = super::FindExprBySpan::new(span);
let mut expr_finder = super::FindExprBySpan::new(span, self.tcx);
let Some(body_id) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) else {
return false;
};

View File

@ -2457,7 +2457,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
&& let Some(body_id) =
self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id)
{
let mut expr_finder = FindExprBySpan::new(span);
let mut expr_finder = FindExprBySpan::new(span, self.tcx);
expr_finder.visit_expr(self.tcx.hir().body(body_id).value);
if let Some(hir::Expr {

View File

@ -12,7 +12,10 @@ note: if `S<()>` implemented `Clone`, you could clone the value
--> $DIR/issue-25700.rs:1:1
|
LL | struct S<T: 'static>(#[allow(dead_code)] Option<&'static T>);
| ^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | drop(t);
| - you could clone this value
error: aborting due to 1 previous error

View File

@ -23,6 +23,13 @@ LL | fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
| | value moved here
| move occurs because `x` has type `T`, which does not implement the `Copy` trait
|
help: if `T` implemented `Clone`, you could clone the value
--> $DIR/typeck-auto-trait-no-supertraits-2.rs:8:9
|
LL | fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
| ^ - you could clone this value
| |
| consider constraining this type parameter with `Clone`
help: consider further restricting this bound
|
LL | fn copy<T: Magic + Copy>(x: T) -> (T, T) { (x, x) }

View File

@ -8,6 +8,13 @@ LL | lhs + rhs;
LL | drop(lhs);
| ^^^ value used here after move
|
help: if `A` implemented `Clone`, you could clone the value
--> $DIR/binop-consume-args.rs:5:8
|
LL | fn add<A: Add<B, Output=()>, B>(lhs: A, rhs: B) {
| ^ consider constraining this type parameter with `Clone`
LL | lhs + rhs;
| --- you could clone this value
note: calling this operator moves the left-hand side
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
help: consider further restricting this bound
@ -26,6 +33,13 @@ LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
|
help: if `B` implemented `Clone`, you could clone the value
--> $DIR/binop-consume-args.rs:5:30
|
LL | fn add<A: Add<B, Output=()>, B>(lhs: A, rhs: B) {
| ^ consider constraining this type parameter with `Clone`
LL | lhs + rhs;
| --- you could clone this value
help: consider restricting type parameter `B`
|
LL | fn add<A: Add<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
@ -41,6 +55,13 @@ LL | lhs - rhs;
LL | drop(lhs);
| ^^^ value used here after move
|
help: if `A` implemented `Clone`, you could clone the value
--> $DIR/binop-consume-args.rs:11:8
|
LL | fn sub<A: Sub<B, Output=()>, B>(lhs: A, rhs: B) {
| ^ consider constraining this type parameter with `Clone`
LL | lhs - rhs;
| --- you could clone this value
note: calling this operator moves the left-hand side
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
help: consider further restricting this bound
@ -59,6 +80,13 @@ LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
|
help: if `B` implemented `Clone`, you could clone the value
--> $DIR/binop-consume-args.rs:11:30
|
LL | fn sub<A: Sub<B, Output=()>, B>(lhs: A, rhs: B) {
| ^ consider constraining this type parameter with `Clone`
LL | lhs - rhs;
| --- you could clone this value
help: consider restricting type parameter `B`
|
LL | fn sub<A: Sub<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
@ -74,6 +102,13 @@ LL | lhs * rhs;
LL | drop(lhs);
| ^^^ value used here after move
|
help: if `A` implemented `Clone`, you could clone the value
--> $DIR/binop-consume-args.rs:17:8
|
LL | fn mul<A: Mul<B, Output=()>, B>(lhs: A, rhs: B) {
| ^ consider constraining this type parameter with `Clone`
LL | lhs * rhs;
| --- you could clone this value
note: calling this operator moves the left-hand side
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
help: consider further restricting this bound
@ -92,6 +127,13 @@ LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
|
help: if `B` implemented `Clone`, you could clone the value
--> $DIR/binop-consume-args.rs:17:30
|
LL | fn mul<A: Mul<B, Output=()>, B>(lhs: A, rhs: B) {
| ^ consider constraining this type parameter with `Clone`
LL | lhs * rhs;
| --- you could clone this value
help: consider restricting type parameter `B`
|
LL | fn mul<A: Mul<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
@ -107,6 +149,13 @@ LL | lhs / rhs;
LL | drop(lhs);
| ^^^ value used here after move
|
help: if `A` implemented `Clone`, you could clone the value
--> $DIR/binop-consume-args.rs:23:8
|
LL | fn div<A: Div<B, Output=()>, B>(lhs: A, rhs: B) {
| ^ consider constraining this type parameter with `Clone`
LL | lhs / rhs;
| --- you could clone this value
note: calling this operator moves the left-hand side
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
help: consider further restricting this bound
@ -125,6 +174,13 @@ LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
|
help: if `B` implemented `Clone`, you could clone the value
--> $DIR/binop-consume-args.rs:23:30
|
LL | fn div<A: Div<B, Output=()>, B>(lhs: A, rhs: B) {
| ^ consider constraining this type parameter with `Clone`
LL | lhs / rhs;
| --- you could clone this value
help: consider restricting type parameter `B`
|
LL | fn div<A: Div<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
@ -140,6 +196,13 @@ LL | lhs % rhs;
LL | drop(lhs);
| ^^^ value used here after move
|
help: if `A` implemented `Clone`, you could clone the value
--> $DIR/binop-consume-args.rs:29:8
|
LL | fn rem<A: Rem<B, Output=()>, B>(lhs: A, rhs: B) {
| ^ consider constraining this type parameter with `Clone`
LL | lhs % rhs;
| --- you could clone this value
note: calling this operator moves the left-hand side
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
help: consider further restricting this bound
@ -158,6 +221,13 @@ LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
|
help: if `B` implemented `Clone`, you could clone the value
--> $DIR/binop-consume-args.rs:29:30
|
LL | fn rem<A: Rem<B, Output=()>, B>(lhs: A, rhs: B) {
| ^ consider constraining this type parameter with `Clone`
LL | lhs % rhs;
| --- you could clone this value
help: consider restricting type parameter `B`
|
LL | fn rem<A: Rem<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
@ -173,6 +243,13 @@ LL | lhs & rhs;
LL | drop(lhs);
| ^^^ value used here after move
|
help: if `A` implemented `Clone`, you could clone the value
--> $DIR/binop-consume-args.rs:35:11
|
LL | fn bitand<A: BitAnd<B, Output=()>, B>(lhs: A, rhs: B) {
| ^ consider constraining this type parameter with `Clone`
LL | lhs & rhs;
| --- you could clone this value
note: calling this operator moves the left-hand side
--> $SRC_DIR/core/src/ops/bit.rs:LL:COL
help: consider further restricting this bound
@ -191,6 +268,13 @@ LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
|
help: if `B` implemented `Clone`, you could clone the value
--> $DIR/binop-consume-args.rs:35:36
|
LL | fn bitand<A: BitAnd<B, Output=()>, B>(lhs: A, rhs: B) {
| ^ consider constraining this type parameter with `Clone`
LL | lhs & rhs;
| --- you could clone this value
help: consider restricting type parameter `B`
|
LL | fn bitand<A: BitAnd<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
@ -206,6 +290,13 @@ LL | lhs | rhs;
LL | drop(lhs);
| ^^^ value used here after move
|
help: if `A` implemented `Clone`, you could clone the value
--> $DIR/binop-consume-args.rs:41:10
|
LL | fn bitor<A: BitOr<B, Output=()>, B>(lhs: A, rhs: B) {
| ^ consider constraining this type parameter with `Clone`
LL | lhs | rhs;
| --- you could clone this value
note: calling this operator moves the left-hand side
--> $SRC_DIR/core/src/ops/bit.rs:LL:COL
help: consider further restricting this bound
@ -224,6 +315,13 @@ LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
|
help: if `B` implemented `Clone`, you could clone the value
--> $DIR/binop-consume-args.rs:41:34
|
LL | fn bitor<A: BitOr<B, Output=()>, B>(lhs: A, rhs: B) {
| ^ consider constraining this type parameter with `Clone`
LL | lhs | rhs;
| --- you could clone this value
help: consider restricting type parameter `B`
|
LL | fn bitor<A: BitOr<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
@ -239,6 +337,13 @@ LL | lhs ^ rhs;
LL | drop(lhs);
| ^^^ value used here after move
|
help: if `A` implemented `Clone`, you could clone the value
--> $DIR/binop-consume-args.rs:47:11
|
LL | fn bitxor<A: BitXor<B, Output=()>, B>(lhs: A, rhs: B) {
| ^ consider constraining this type parameter with `Clone`
LL | lhs ^ rhs;
| --- you could clone this value
note: calling this operator moves the left-hand side
--> $SRC_DIR/core/src/ops/bit.rs:LL:COL
help: consider further restricting this bound
@ -257,6 +362,13 @@ LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
|
help: if `B` implemented `Clone`, you could clone the value
--> $DIR/binop-consume-args.rs:47:36
|
LL | fn bitxor<A: BitXor<B, Output=()>, B>(lhs: A, rhs: B) {
| ^ consider constraining this type parameter with `Clone`
LL | lhs ^ rhs;
| --- you could clone this value
help: consider restricting type parameter `B`
|
LL | fn bitxor<A: BitXor<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
@ -272,6 +384,13 @@ LL | lhs << rhs;
LL | drop(lhs);
| ^^^ value used here after move
|
help: if `A` implemented `Clone`, you could clone the value
--> $DIR/binop-consume-args.rs:53:8
|
LL | fn shl<A: Shl<B, Output=()>, B>(lhs: A, rhs: B) {
| ^ consider constraining this type parameter with `Clone`
LL | lhs << rhs;
| --- you could clone this value
note: calling this operator moves the left-hand side
--> $SRC_DIR/core/src/ops/bit.rs:LL:COL
help: consider further restricting this bound
@ -290,6 +409,13 @@ LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
|
help: if `B` implemented `Clone`, you could clone the value
--> $DIR/binop-consume-args.rs:53:30
|
LL | fn shl<A: Shl<B, Output=()>, B>(lhs: A, rhs: B) {
| ^ consider constraining this type parameter with `Clone`
LL | lhs << rhs;
| --- you could clone this value
help: consider restricting type parameter `B`
|
LL | fn shl<A: Shl<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
@ -305,6 +431,13 @@ LL | lhs >> rhs;
LL | drop(lhs);
| ^^^ value used here after move
|
help: if `A` implemented `Clone`, you could clone the value
--> $DIR/binop-consume-args.rs:59:8
|
LL | fn shr<A: Shr<B, Output=()>, B>(lhs: A, rhs: B) {
| ^ consider constraining this type parameter with `Clone`
LL | lhs >> rhs;
| --- you could clone this value
note: calling this operator moves the left-hand side
--> $SRC_DIR/core/src/ops/bit.rs:LL:COL
help: consider further restricting this bound
@ -323,6 +456,13 @@ LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
|
help: if `B` implemented `Clone`, you could clone the value
--> $DIR/binop-consume-args.rs:59:30
|
LL | fn shr<A: Shr<B, Output=()>, B>(lhs: A, rhs: B) {
| ^ consider constraining this type parameter with `Clone`
LL | lhs >> rhs;
| --- you could clone this value
help: consider restricting type parameter `B`
|
LL | fn shr<A: Shr<B, Output=()>, B: Copy>(lhs: A, rhs: B) {

View File

@ -11,6 +11,13 @@ LL | | x;
| |_____value used here after move
| `x` moved due to usage in operator
|
help: if `T` implemented `Clone`, you could clone the value
--> $DIR/binop-move-semantics.rs:5:16
|
LL | fn double_move<T: Add<Output=()>>(x: T) {
| ^ consider constraining this type parameter with `Clone`
LL | x
| - you could clone this value
note: calling this operator moves the left-hand side
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
help: consider further restricting this bound
@ -51,6 +58,14 @@ LL | x
...
LL | use_mut(n); use_imm(m);
| - borrow later used here
|
help: if `T` implemented `Clone`, you could clone the value
--> $DIR/binop-move-semantics.rs:17:18
|
LL | fn move_borrowed<T: Add<Output=()>>(x: T, mut y: T) {
| ^ consider constraining this type parameter with `Clone`
LL | let m = &x;
| -- you could clone this value
error[E0505]: cannot move out of `y` because it is borrowed
--> $DIR/binop-move-semantics.rs:23:5
@ -65,6 +80,15 @@ LL | y;
| ^ move out of `y` occurs here
LL | use_mut(n); use_imm(m);
| - borrow later used here
|
help: if `T` implemented `Clone`, you could clone the value
--> $DIR/binop-move-semantics.rs:17:18
|
LL | fn move_borrowed<T: Add<Output=()>>(x: T, mut y: T) {
| ^ consider constraining this type parameter with `Clone`
LL | let m = &x;
LL | let n = &mut y;
| ------ you could clone this value
error[E0507]: cannot move out of `*m` which is behind a mutable reference
--> $DIR/binop-move-semantics.rs:30:5
@ -80,12 +104,29 @@ LL | | *n;
|
note: calling this operator moves the left-hand side
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
help: if `T` implemented `Clone`, you could clone the value
--> $DIR/binop-move-semantics.rs:26:24
|
LL | fn illegal_dereference<T: Add<Output=()>>(mut x: T, y: T) {
| ^ consider constraining this type parameter with `Clone`
...
LL | *m
| -- you could clone this value
error[E0507]: cannot move out of `*n` which is behind a shared reference
--> $DIR/binop-move-semantics.rs:32:5
|
LL | *n;
| ^^ move occurs because `*n` has type `T`, which does not implement the `Copy` trait
|
help: if `T` implemented `Clone`, you could clone the value
--> $DIR/binop-move-semantics.rs:26:24
|
LL | fn illegal_dereference<T: Add<Output=()>>(mut x: T, y: T) {
| ^ consider constraining this type parameter with `Clone`
...
LL | *n;
| -- you could clone this value
error[E0502]: cannot borrow `f` as immutable because it is also borrowed as mutable
--> $DIR/binop-move-semantics.rs:54:5

View File

@ -11,6 +11,12 @@ LL | let _h = to_fn_once(move || -> isize { *bar });
| | variable moved due to use in closure
| | move occurs because `bar` has type `Box<isize>`, which does not implement the `Copy` trait
| `bar` is moved here
|
help: clone the value before moving it into the closure
|
LL ~ let value = bar.clone();
LL ~ let _h = to_fn_once(move || -> isize { value });
|
error: aborting due to 1 previous error

View File

@ -8,7 +8,10 @@ note: if `Foo` implemented `Clone`, you could clone the value
--> $DIR/borrowck-move-out-of-static-item.rs:3:1
|
LL | struct Foo {
| ^^^^^^^^^^
| ^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | test(BAR);
| --- you could clone this value
error: aborting due to 1 previous error

View File

@ -14,7 +14,10 @@ note: if `S` implemented `Clone`, you could clone the value
--> $DIR/borrowck-move-subcomponent.rs:6:1
|
LL | struct S {
| ^^^^^^^^
| ^^^^^^^^ consider implementing `Clone` for this type
...
LL | let pb = &a;
| -- you could clone this value
error: aborting due to 1 previous error

View File

@ -34,7 +34,10 @@ note: if `SFnOnce` implemented `Clone`, you could clone the value
--> $DIR/borrowck-overloaded-call.rs:41:1
|
LL | struct SFnOnce {
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | s(" world".to_string());
| - you could clone this value
error: aborting due to 3 previous errors

View File

@ -32,6 +32,13 @@ LL |
LL | println!("{b}");
| --- borrow later used here
|
help: if `T` implemented `Clone`, you could clone the value
--> $DIR/clone-on-ref.rs:11:8
|
LL | fn bar<T: std::fmt::Display>(x: T) {
| ^ consider constraining this type parameter with `Clone`
LL | let a = &x;
| -- you could clone this value
help: consider further restricting this bound
|
LL | fn bar<T: std::fmt::Display + Clone>(x: T) {
@ -56,7 +63,10 @@ note: if `A` implemented `Clone`, you could clone the value
--> $DIR/clone-on-ref.rs:19:1
|
LL | struct A;
| ^^^^^^^^
| ^^^^^^^^ consider implementing `Clone` for this type
LL | fn qux(x: A) {
LL | let a = &x;
| -- you could clone this value
help: consider annotating `A` with `#[derive(Clone)]`
|
LL + #[derive(Clone)]

View File

@ -22,7 +22,10 @@ note: if `State` implemented `Clone`, you could clone the value
--> $DIR/issue-101119.rs:1:1
|
LL | struct State;
| ^^^^^^^^^^^^
| ^^^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | fill_segment(state);
| ----- you could clone this value
error: aborting due to 1 previous error

View File

@ -13,8 +13,11 @@ LL | self.b;
note: if `StructB` implemented `Clone`, you could clone the value
--> $DIR/issue-103624.rs:23:1
|
LL | self.b;
| ------ you could clone this value
...
LL | struct StructB {}
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ consider implementing `Clone` for this type
error[E0521]: borrowed data escapes outside of method
--> $DIR/issue-103624.rs:14:9

View File

@ -15,7 +15,10 @@ note: if `Example<E, NoLifetime>` implemented `Clone`, you could clone the value
--> $DIR/issue-119915-bad-clone-suggestion.rs:3:1
|
LL | struct Example<E, FakeParam>(PhantomData<(fn(E), fn(FakeParam))>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | unsafe { self.change() }
| ---- you could clone this value
error: aborting due to 1 previous error

View File

@ -8,7 +8,10 @@ note: if `Foo` implemented `Clone`, you could clone the value
--> $DIR/issue-17718-static-move.rs:1:1
|
LL | struct Foo;
| ^^^^^^^^^^
| ^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | let _a = FOO;
| --- you could clone this value
help: consider borrowing here
|
LL | let _a = &FOO;

View File

@ -23,7 +23,10 @@ note: if `T` implemented `Clone`, you could clone the value
--> $DIR/issue-20801.rs:3:1
|
LL | struct T(u8);
| ^^^^^^^^
| ^^^^^^^^ consider implementing `Clone` for this type
...
LL | let a = unsafe { *mut_ref() };
| ---------- you could clone this value
help: consider removing the dereference here
|
LL - let a = unsafe { *mut_ref() };
@ -40,7 +43,10 @@ note: if `T` implemented `Clone`, you could clone the value
--> $DIR/issue-20801.rs:3:1
|
LL | struct T(u8);
| ^^^^^^^^
| ^^^^^^^^ consider implementing `Clone` for this type
...
LL | let b = unsafe { *imm_ref() };
| ---------- you could clone this value
help: consider removing the dereference here
|
LL - let b = unsafe { *imm_ref() };
@ -57,7 +63,10 @@ note: if `T` implemented `Clone`, you could clone the value
--> $DIR/issue-20801.rs:3:1
|
LL | struct T(u8);
| ^^^^^^^^
| ^^^^^^^^ consider implementing `Clone` for this type
...
LL | let c = unsafe { *mut_ptr() };
| ---------- you could clone this value
help: consider removing the dereference here
|
LL - let c = unsafe { *mut_ptr() };
@ -74,7 +83,10 @@ note: if `T` implemented `Clone`, you could clone the value
--> $DIR/issue-20801.rs:3:1
|
LL | struct T(u8);
| ^^^^^^^^
| ^^^^^^^^ consider implementing `Clone` for this type
...
LL | let d = unsafe { *const_ptr() };
| ------------ you could clone this value
help: consider removing the dereference here
|
LL - let d = unsafe { *const_ptr() };

View File

@ -11,7 +11,10 @@ note: if `S` implemented `Clone`, you could clone the value
--> $DIR/move-error-in-promoted-2.rs:3:1
|
LL | struct S;
| ^^^^^^^^
| ^^^^^^^^ consider implementing `Clone` for this type
...
LL | &([S][0],);
| ------ you could clone this value
error: aborting due to 1 previous error

View File

@ -13,7 +13,12 @@ note: if `A` implemented `Clone`, you could clone the value
--> $DIR/move-error-snippets.rs:9:1
|
LL | struct A;
| ^^^^^^^^
| ^^^^^^^^ consider implementing `Clone` for this type
|
::: $DIR/move-error-snippets-ext.rs:5:17
|
LL | let a = $c;
| -- you could clone this value
= note: this error originates in the macro `aaa` which comes from the expansion of the macro `sss` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider borrowing here
|

View File

@ -8,7 +8,10 @@ note: if `Foo` implemented `Clone`, you could clone the value
--> $DIR/move-in-static-initializer-issue-38520.rs:5:1
|
LL | struct Foo(usize);
| ^^^^^^^^^^
| ^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | static Y: usize = get(*&X);
| --- you could clone this value
error[E0507]: cannot move out of a shared reference
--> $DIR/move-in-static-initializer-issue-38520.rs:13:22
@ -20,7 +23,10 @@ note: if `Foo` implemented `Clone`, you could clone the value
--> $DIR/move-in-static-initializer-issue-38520.rs:5:1
|
LL | struct Foo(usize);
| ^^^^^^^^^^
| ^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | const Z: usize = get(*&X);
| --- you could clone this value
error: aborting due to 2 previous errors

View File

@ -16,7 +16,10 @@ note: if `Alloc` implemented `Clone`, you could clone the value
--> $DIR/leak-alloc.rs:8:1
|
LL | struct Alloc {}
| ^^^^^^^^^^^^
| ^^^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | let boxed = Box::new_in(10, alloc.by_ref());
| ----- you could clone this value
error: aborting due to 1 previous error

View File

@ -4,6 +4,7 @@ error[E0597]: `a` does not live long enough
LL | let _b = {
| -- borrow later stored here
LL | let a = 3;
| - binding `a` declared here
LL | Pin::new(&mut #[coroutine] || yield &a).resume(())
| -- ^ borrowed value does not live long enough
| |
@ -18,6 +19,7 @@ error[E0597]: `a` does not live long enough
LL | let _b = {
| -- borrow later stored here
LL | let a = 3;
| - binding `a` declared here
LL | #[coroutine] || {
| -- value captured here by coroutine
LL | yield &a

View File

@ -18,6 +18,9 @@ LL | }
error[E0597]: `ref_` does not live long enough
--> $DIR/dropck.rs:16:18
|
LL | let ref_ = Box::leak(Box::new(Some(cell.borrow_mut())));
| ---- binding `ref_` declared here
...
LL | || {
| -- value captured here by coroutine
LL | // but the coroutine can use it to drop a `Ref<'a, i32>`.

View File

@ -40,7 +40,10 @@ note: if `Y` implemented `Clone`, you could clone the value
--> $DIR/deriving-with-repr-packed.rs:16:1
|
LL | struct Y(usize);
| ^^^^^^^^
| ^^^^^^^^ consider implementing `Clone` for this type
...
LL | struct X(Y);
| - you could clone this value
= note: `#[derive(Debug)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@ -18,7 +18,10 @@ note: if `FancyNum` implemented `Clone`, you could clone the value
--> $DIR/E0504.rs:1:1
|
LL | struct FancyNum {
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | let fancy_ref = &fancy_num;
| ---------- you could clone this value
error: aborting due to 1 previous error

View File

@ -15,7 +15,10 @@ note: if `Value` implemented `Clone`, you could clone the value
--> $DIR/E0505.rs:1:1
|
LL | struct Value {}
| ^^^^^^^^^^^^
| ^^^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | let _ref_to_val: &Value = &x;
| -- you could clone this value
error: aborting due to 1 previous error

View File

@ -15,7 +15,10 @@ note: if `TheDarkKnight` implemented `Clone`, you could clone the value
--> $DIR/E0507.rs:3:1
|
LL | struct TheDarkKnight;
| ^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | x.borrow().nothing_is_true();
| ---------- you could clone this value
error: aborting due to 1 previous error

View File

@ -11,7 +11,10 @@ note: if `NonCopy` implemented `Clone`, you could clone the value
--> $DIR/E0508-fail.rs:1:1
|
LL | struct NonCopy;
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | let _value = array[0];
| -------- you could clone this value
help: consider borrowing here
|
LL | let _value = &array[0];

View File

@ -11,7 +11,10 @@ note: if `NonCopy` implemented `Clone`, you could clone the value
--> $DIR/E0508.rs:1:1
|
LL | struct NonCopy;
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | let _value = array[0];
| -------- you could clone this value
help: consider borrowing here
|
LL | let _value = &array[0];

View File

@ -11,7 +11,10 @@ note: if `FancyNum` implemented `Clone`, you could clone the value
--> $DIR/E0509.rs:1:1
|
LL | struct FancyNum {
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | let fancy_field = drop_struct.fancy;
| ----------------- you could clone this value
help: consider borrowing here
|
LL | let fancy_field = &drop_struct.fancy;

View File

@ -18,6 +18,7 @@ fn fn_mut() -> _ {
//~| NOTE for more information on `Fn` traits and closure types
let x = String::new();
//~^ HELP: consider changing this to be mutable
//~| NOTE binding `x` declared here
|c| { //~ NOTE: value captured here
x.push(c);
//~^ ERROR: does not live long enough

View File

@ -21,7 +21,7 @@ LL | fn fn_mut() -> _ {
= note: for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
--> $DIR/suggest-return-closure.rs:31:13
--> $DIR/suggest-return-closure.rs:32:13
|
LL | fn fun() -> _ {
| ^
@ -32,7 +32,7 @@ LL | fn fun() -> _ {
= note: for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/suggest-return-closure.rs:22:9
--> $DIR/suggest-return-closure.rs:23:9
|
LL | let x = String::new();
| - help: consider changing this to be mutable: `mut x`
@ -41,8 +41,11 @@ LL | x.push(c);
| ^ cannot borrow as mutable
error[E0597]: `x` does not live long enough
--> $DIR/suggest-return-closure.rs:22:9
--> $DIR/suggest-return-closure.rs:23:9
|
LL | let x = String::new();
| - binding `x` declared here
...
LL | |c| {
| --- value captured here
LL | x.push(c);

View File

@ -12,7 +12,10 @@ note: if `X` implemented `Clone`, you could clone the value
--> $DIR/issue-17385.rs:1:1
|
LL | struct X(isize);
| ^^^^^^^^
| ^^^^^^^^ consider implementing `Clone` for this type
...
LL | drop(foo);
| --- you could clone this value
error[E0382]: use of moved value: `e`
--> $DIR/issue-17385.rs:25:11
@ -28,7 +31,10 @@ note: if `Enum` implemented `Clone`, you could clone the value
--> $DIR/issue-17385.rs:3:1
|
LL | enum Enum {
| ^^^^^^^^^
| ^^^^^^^^^ consider implementing `Clone` for this type
...
LL | drop(e);
| - you could clone this value
error: aborting due to 2 previous errors

View File

@ -1,10 +1,12 @@
struct NoCopy; //~ NOTE if `NoCopy` implemented `Clone`, you could clone the value
//~^ NOTE consider implementing `Clone` for this type
fn main() {
let x = NoCopy;
//~^ NOTE move occurs because `x` has type `NoCopy`
let f = move || { let y = x; };
//~^ NOTE value moved into closure here
//~| NOTE variable moved due to use in closure
//~| NOTE you could clone this value
let z = x;
//~^ ERROR use of moved value: `x`
//~| NOTE value used here after move

View File

@ -1,5 +1,5 @@
error[E0382]: use of moved value: `x`
--> $DIR/issue-24357.rs:8:12
--> $DIR/issue-24357.rs:10:12
|
LL | let x = NoCopy;
| - move occurs because `x` has type `NoCopy`, which does not implement the `Copy` trait
@ -16,7 +16,10 @@ note: if `NoCopy` implemented `Clone`, you could clone the value
--> $DIR/issue-24357.rs:1:1
|
LL | struct NoCopy;
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | let f = move || { let y = x; };
| - you could clone this value
error: aborting due to 1 previous error

View File

@ -7,6 +7,14 @@ LL | id(Box::new(|| *v))
| -- ^^ move occurs because `*v` has type `T`, which does not implement the `Copy` trait
| |
| captured by this `FnMut` closure
|
help: if `T` implemented `Clone`, you could clone the value
--> $DIR/issue-4335.rs:5:10
|
LL | fn f<'r, T>(v: &'r T) -> Box<dyn FnMut() -> T + 'r> {
| ^ consider constraining this type parameter with `Clone`
LL | id(Box::new(|| *v))
| -- you could clone this value
error: aborting due to 1 previous error

View File

@ -8,7 +8,10 @@ note: if `Enum` implemented `Clone`, you could clone the value
--> $DIR/issue-102389.rs:1:1
|
LL | enum Enum { A, B, C }
| ^^^^^^^^^
| ^^^^^^^^^ consider implementing `Clone` for this type
...
LL | array[*inbounds as usize]
| --------- you could clone this value
error: aborting due to 1 previous error

View File

@ -1,4 +1,4 @@
fn takes_fn(f: impl Fn()) {
fn takes_fn(f: impl Fn()) { //~ HELP if `impl Fn()` implemented `Clone`
loop {
takes_fnonce(f);
//~^ ERROR use of moved value
@ -6,7 +6,7 @@ fn takes_fn(f: impl Fn()) {
}
}
fn takes_fn_mut(m: impl FnMut()) {
fn takes_fn_mut(m: impl FnMut()) { //~ HELP if `impl FnMut()` implemented `Clone`
if maybe() {
takes_fnonce(m);
//~^ HELP consider mutably borrowing

View File

@ -15,6 +15,14 @@ LL | fn takes_fnonce(_: impl FnOnce()) {}
| ------------ ^^^^^^^^^^^^^ this parameter takes ownership of the value
| |
| in this function
help: if `impl Fn()` implemented `Clone`, you could clone the value
--> $DIR/borrow-closures-instead-of-move.rs:1:16
|
LL | fn takes_fn(f: impl Fn()) {
| ^^^^^^^^^ consider constraining this type parameter with `Clone`
LL | loop {
LL | takes_fnonce(f);
| - you could clone this value
help: consider borrowing `f`
|
LL | takes_fnonce(&f);
@ -39,6 +47,14 @@ LL | fn takes_fnonce(_: impl FnOnce()) {}
| ------------ ^^^^^^^^^^^^^ this parameter takes ownership of the value
| |
| in this function
help: if `impl FnMut()` implemented `Clone`, you could clone the value
--> $DIR/borrow-closures-instead-of-move.rs:9:20
|
LL | fn takes_fn_mut(m: impl FnMut()) {
| ^^^^^^^^^^^^ consider constraining this type parameter with `Clone`
LL | if maybe() {
LL | takes_fnonce(m);
| - you could clone this value
help: consider mutably borrowing `m`
|
LL | takes_fnonce(&mut m);

View File

@ -7,6 +7,10 @@ struct NonCopy;
//~| NOTE if `NonCopy` implemented `Clone`
//~| NOTE if `NonCopy` implemented `Clone`
//~| NOTE if `NonCopy` implemented `Clone`
//~| NOTE consider implementing `Clone` for this type
//~| NOTE consider implementing `Clone` for this type
//~| NOTE consider implementing `Clone` for this type
//~| NOTE consider implementing `Clone` for this type
fn good() {
loop {
@ -21,6 +25,7 @@ fn moved_here_1() {
//~^ NOTE move occurs because `value` has type `NonCopy`, which does not implement the `Copy` trait
let _used = value;
//~^ NOTE value moved here
//~| NOTE you could clone this value
let _used2 = value; //~ ERROR use of moved value: `value`
//~^ NOTE value used here after move
}
@ -32,6 +37,7 @@ fn moved_here_2() {
loop { //~ NOTE inside of this loop
let _used = value;
//~^ NOTE value moved here
//~| NOTE you could clone this value
loop {
let _used2 = value; //~ ERROR use of moved value: `value`
//~^ NOTE value used here after move
@ -45,6 +51,7 @@ fn moved_loop_1() {
loop { //~ NOTE inside of this loop
let _used = value; //~ ERROR use of moved value: `value`
//~^ NOTE value moved here, in previous iteration of loop
//~| NOTE you could clone this value
}
}
@ -56,6 +63,7 @@ fn moved_loop_2() {
loop { //~ NOTE inside of this loop
let _used2 = value; //~ ERROR use of moved value: `value`
//~^ NOTE value moved here, in previous iteration of loop
//~| NOTE you could clone this value
}
}

View File

@ -1,12 +1,12 @@
error[E0382]: use of moved value: `value`
--> $DIR/issue-72649-uninit-in-loop.rs:24:22
--> $DIR/issue-72649-uninit-in-loop.rs:29:22
|
LL | let value = NonCopy{};
| ----- move occurs because `value` has type `NonCopy`, which does not implement the `Copy` trait
LL |
LL | let _used = value;
| ----- value moved here
LL |
...
LL | let _used2 = value;
| ^^^^^ value used here after move
|
@ -14,10 +14,13 @@ note: if `NonCopy` implemented `Clone`, you could clone the value
--> $DIR/issue-72649-uninit-in-loop.rs:5:1
|
LL | struct NonCopy;
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | let _used = value;
| ----- you could clone this value
error[E0382]: use of moved value: `value`
--> $DIR/issue-72649-uninit-in-loop.rs:36:26
--> $DIR/issue-72649-uninit-in-loop.rs:42:26
|
LL | let value = NonCopy{};
| ----- move occurs because `value` has type `NonCopy`, which does not implement the `Copy` trait
@ -34,10 +37,13 @@ note: if `NonCopy` implemented `Clone`, you could clone the value
--> $DIR/issue-72649-uninit-in-loop.rs:5:1
|
LL | struct NonCopy;
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | let _used = value;
| ----- you could clone this value
error[E0382]: use of moved value: `value`
--> $DIR/issue-72649-uninit-in-loop.rs:46:21
--> $DIR/issue-72649-uninit-in-loop.rs:52:21
|
LL | let value = NonCopy{};
| ----- move occurs because `value` has type `NonCopy`, which does not implement the `Copy` trait
@ -51,10 +57,13 @@ note: if `NonCopy` implemented `Clone`, you could clone the value
--> $DIR/issue-72649-uninit-in-loop.rs:5:1
|
LL | struct NonCopy;
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | let _used = value;
| ----- you could clone this value
error[E0382]: use of moved value: `value`
--> $DIR/issue-72649-uninit-in-loop.rs:57:22
--> $DIR/issue-72649-uninit-in-loop.rs:64:22
|
LL | let mut value = NonCopy{};
| --------- move occurs because `value` has type `NonCopy`, which does not implement the `Copy` trait
@ -68,10 +77,13 @@ note: if `NonCopy` implemented `Clone`, you could clone the value
--> $DIR/issue-72649-uninit-in-loop.rs:5:1
|
LL | struct NonCopy;
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | let _used2 = value;
| ----- you could clone this value
error[E0381]: used binding `value` isn't initialized
--> $DIR/issue-72649-uninit-in-loop.rs:65:21
--> $DIR/issue-72649-uninit-in-loop.rs:73:21
|
LL | let value: NonCopy;
| ----- binding declared here but left uninitialized
@ -84,7 +96,7 @@ LL | let value: NonCopy = /* value */;
| +++++++++++++
error[E0381]: used binding `value` isn't initialized
--> $DIR/issue-72649-uninit-in-loop.rs:73:21
--> $DIR/issue-72649-uninit-in-loop.rs:81:21
|
LL | let mut value: NonCopy;
| --------- binding declared here but left uninitialized

View File

@ -15,7 +15,10 @@ note: if `NotCopy` implemented `Clone`, you could clone the value
--> $DIR/issue-75904-move-closure-loop.rs:5:1
|
LL | struct NotCopy;
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | a;
| - you could clone this value
error: aborting due to 1 previous error

View File

@ -106,7 +106,10 @@ note: if `Foo` implemented `Clone`, you could clone the value
--> $DIR/move-fn-self-receiver.rs:5:1
|
LL | struct Foo;
| ^^^^^^^^^^
| ^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | let ret = mut_foo.use_mut_self();
| ------- you could clone this value
error[E0382]: use of moved value: `rc_foo`
--> $DIR/move-fn-self-receiver.rs:55:5
@ -142,7 +145,10 @@ note: if `Foo` implemented `Clone`, you could clone the value
--> $DIR/move-fn-self-receiver.rs:5:1
|
LL | struct Foo;
| ^^^^^^^^^^
| ^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | foo_add + Foo;
| ------- you could clone this value
note: calling this operator moves the left-hand side
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL

View File

@ -11,7 +11,10 @@ note: if `D` implemented `Clone`, you could clone the value
--> $DIR/move-out-of-array-1.rs:5:1
|
LL | struct D { _x: u8 }
| ^^^^^^^^
| ^^^^^^^^ consider implementing `Clone` for this type
...
LL | a[i]
| ---- you could clone this value
error: aborting due to 1 previous error

View File

@ -17,6 +17,13 @@ LL | let mut r = R {c: Box::new(f)};
LL | f(&mut r, false)
| ^ value borrowed here after move
|
help: if `F` implemented `Clone`, you could clone the value
--> $DIR/moves-based-on-type-no-recursive-stack-closure.rs:30:16
|
LL | fn conspirator<F>(mut f: F) where F: FnMut(&mut R, bool) {
| ^ consider constraining this type parameter with `Clone`
LL | let mut r = R {c: Box::new(f)};
| - you could clone this value
help: consider mutably borrowing `f`
|
LL | let mut r = R {c: Box::new(&mut f)};

View File

@ -3,6 +3,7 @@
fn duplicate_t<T: Copy>(t: T) -> (T, T) {
//~^ HELP consider restricting type parameter `T`
//~| HELP if `T` implemented `Clone`, you could clone the value
(t, t) //~ use of moved value: `t`
}
@ -72,10 +73,11 @@ where
#[rustfmt::skip]
fn existing_colon<T: Copy>(t: T) {
//~^ HELP consider restricting type parameter `T`
//~| HELP if `T` implemented `Clone`, you could clone the value
[t, t]; //~ use of moved value: `t`
}
fn existing_colon_in_where<T>(t: T)
fn existing_colon_in_where<T>(t: T) //~ HELP if `T` implemented `Clone`, you could clone the value
where
T:, T: Copy
//~^ HELP consider further restricting type parameter `T`

View File

@ -3,6 +3,7 @@
fn duplicate_t<T>(t: T) -> (T, T) {
//~^ HELP consider restricting type parameter `T`
//~| HELP if `T` implemented `Clone`, you could clone the value
(t, t) //~ use of moved value: `t`
}
@ -72,10 +73,11 @@ where
#[rustfmt::skip]
fn existing_colon<T:>(t: T) {
//~^ HELP consider restricting type parameter `T`
//~| HELP if `T` implemented `Clone`, you could clone the value
[t, t]; //~ use of moved value: `t`
}
fn existing_colon_in_where<T>(t: T)
fn existing_colon_in_where<T>(t: T) //~ HELP if `T` implemented `Clone`, you could clone the value
where
T:,
//~^ HELP consider further restricting type parameter `T`

View File

@ -1,21 +1,29 @@
error[E0382]: use of moved value: `t`
--> $DIR/use_of_moved_value_copy_suggestions.rs:6:9
--> $DIR/use_of_moved_value_copy_suggestions.rs:7:9
|
LL | fn duplicate_t<T>(t: T) -> (T, T) {
| - move occurs because `t` has type `T`, which does not implement the `Copy` trait
LL |
...
LL | (t, t)
| - ^ value used here after move
| |
| value moved here
|
help: if `T` implemented `Clone`, you could clone the value
--> $DIR/use_of_moved_value_copy_suggestions.rs:4:16
|
LL | fn duplicate_t<T>(t: T) -> (T, T) {
| ^ consider constraining this type parameter with `Clone`
...
LL | (t, t)
| - you could clone this value
help: consider restricting type parameter `T`
|
LL | fn duplicate_t<T: Copy>(t: T) -> (T, T) {
| ++++++
error[E0382]: use of moved value: `t`
--> $DIR/use_of_moved_value_copy_suggestions.rs:11:9
--> $DIR/use_of_moved_value_copy_suggestions.rs:12:9
|
LL | fn duplicate_opt<T>(t: Option<T>) -> (Option<T>, Option<T>) {
| - move occurs because `t` has type `Option<T>`, which does not implement the `Copy` trait
@ -31,7 +39,7 @@ LL | fn duplicate_opt<T: Copy>(t: Option<T>) -> (Option<T>, Option<T>) {
| ++++++
error[E0382]: use of moved value: `t`
--> $DIR/use_of_moved_value_copy_suggestions.rs:16:9
--> $DIR/use_of_moved_value_copy_suggestions.rs:17:9
|
LL | fn duplicate_tup1<T>(t: (T,)) -> ((T,), (T,)) {
| - move occurs because `t` has type `(T,)`, which does not implement the `Copy` trait
@ -47,7 +55,7 @@ LL | fn duplicate_tup1<T: Copy>(t: (T,)) -> ((T,), (T,)) {
| ++++++
error[E0382]: use of moved value: `t`
--> $DIR/use_of_moved_value_copy_suggestions.rs:21:9
--> $DIR/use_of_moved_value_copy_suggestions.rs:22:9
|
LL | fn duplicate_tup2<A, B>(t: (A, B)) -> ((A, B), (A, B)) {
| - move occurs because `t` has type `(A, B)`, which does not implement the `Copy` trait
@ -63,7 +71,7 @@ LL | fn duplicate_tup2<A: Copy, B: Copy>(t: (A, B)) -> ((A, B), (A, B)) {
| ++++++ ++++++
error[E0382]: use of moved value: `t`
--> $DIR/use_of_moved_value_copy_suggestions.rs:26:9
--> $DIR/use_of_moved_value_copy_suggestions.rs:27:9
|
LL | fn duplicate_custom<T>(t: S<T>) -> (S<T>, S<T>) {
| - move occurs because `t` has type `S<T>`, which does not implement the `Copy` trait
@ -79,7 +87,7 @@ LL | fn duplicate_custom<T: Copy + Trait>(t: S<T>) -> (S<T>, S<T>) {
| ++++++++++++++
error[E0382]: use of moved value: `t`
--> $DIR/use_of_moved_value_copy_suggestions.rs:44:9
--> $DIR/use_of_moved_value_copy_suggestions.rs:45:9
|
LL | fn duplicate_custom_1<T>(t: S<T>) -> (S<T>, S<T>) where {
| - move occurs because `t` has type `S<T>`, which does not implement the `Copy` trait
@ -95,7 +103,7 @@ LL | fn duplicate_custom_1<T: Copy + Trait>(t: S<T>) -> (S<T>, S<T>) where {
| ++++++++++++++
error[E0382]: use of moved value: `t`
--> $DIR/use_of_moved_value_copy_suggestions.rs:52:9
--> $DIR/use_of_moved_value_copy_suggestions.rs:53:9
|
LL | fn duplicate_custom_2<T>(t: S<T>) -> (S<T>, S<T>)
| - move occurs because `t` has type `S<T>`, which does not implement the `Copy` trait
@ -111,7 +119,7 @@ LL | T: A + Copy + Trait,
| ++++++++++++++
error[E0382]: use of moved value: `t`
--> $DIR/use_of_moved_value_copy_suggestions.rs:61:9
--> $DIR/use_of_moved_value_copy_suggestions.rs:62:9
|
LL | fn duplicate_custom_3<T>(t: S<T>) -> (S<T>, S<T>)
| - move occurs because `t` has type `S<T>`, which does not implement the `Copy` trait
@ -127,7 +135,7 @@ LL | T: A + Copy + Trait,
| ++++++++++++++
error[E0382]: use of moved value: `t`
--> $DIR/use_of_moved_value_copy_suggestions.rs:69:9
--> $DIR/use_of_moved_value_copy_suggestions.rs:70:9
|
LL | fn duplicate_custom_4<T: A>(t: S<T>) -> (S<T>, S<T>)
| - move occurs because `t` has type `S<T>`, which does not implement the `Copy` trait
@ -143,23 +151,31 @@ LL | fn duplicate_custom_4<T: A + Copy + Trait>(t: S<T>) -> (S<T>, S<T>)
| ++++++++++++++
error[E0382]: use of moved value: `t`
--> $DIR/use_of_moved_value_copy_suggestions.rs:75:9
--> $DIR/use_of_moved_value_copy_suggestions.rs:77:9
|
LL | fn existing_colon<T:>(t: T) {
| - move occurs because `t` has type `T`, which does not implement the `Copy` trait
LL |
...
LL | [t, t];
| - ^ value used here after move
| |
| value moved here
|
help: if `T` implemented `Clone`, you could clone the value
--> $DIR/use_of_moved_value_copy_suggestions.rs:74:19
|
LL | fn existing_colon<T:>(t: T) {
| ^ consider constraining this type parameter with `Clone`
...
LL | [t, t];
| - you could clone this value
help: consider restricting type parameter `T`
|
LL | fn existing_colon<T: Copy>(t: T) {
| ++++
error[E0382]: use of moved value: `t`
--> $DIR/use_of_moved_value_copy_suggestions.rs:83:9
--> $DIR/use_of_moved_value_copy_suggestions.rs:85:9
|
LL | fn existing_colon_in_where<T>(t: T)
| - move occurs because `t` has type `T`, which does not implement the `Copy` trait
@ -169,6 +185,14 @@ LL | [t, t];
| |
| value moved here
|
help: if `T` implemented `Clone`, you could clone the value
--> $DIR/use_of_moved_value_copy_suggestions.rs:80:28
|
LL | fn existing_colon_in_where<T>(t: T)
| ^ consider constraining this type parameter with `Clone`
...
LL | [t, t];
| - you could clone this value
help: consider further restricting type parameter `T`
|
LL | T:, T: Copy

View File

@ -25,6 +25,8 @@ LL | f.use_ref();
error[E0597]: `x` does not live long enough
--> $DIR/closure-borrow-spans.rs:19:16
|
LL | let x = 1;
| - binding `x` declared here
LL | f = || x;
| -- ^ borrowed value does not live long enough
| |
@ -85,6 +87,8 @@ LL | f.use_ref();
error[E0597]: `x` does not live long enough
--> $DIR/closure-borrow-spans.rs:52:16
|
LL | let mut x = 1;
| ----- binding `x` declared here
LL | f = || x = 0;
| -- ^ borrowed value does not live long enough
| |
@ -145,6 +149,8 @@ LL | f.use_ref();
error[E0597]: `x` does not live long enough
--> $DIR/closure-borrow-spans.rs:86:16
|
LL | let x = &mut z;
| - binding `x` declared here
LL | f = || *x = 0;
| -- ^^ borrowed value does not live long enough
| |

View File

@ -37,6 +37,9 @@ LL | fn test() {
error[E0597]: `y` does not live long enough
--> $DIR/escape-upvar-nested.rs:21:40
|
LL | let y = 22;
| - binding `y` declared here
LL |
LL | let mut closure = || {
| -- value captured here
LL | let mut closure1 = || p = &y;

View File

@ -23,6 +23,8 @@ LL | fn test() {
error[E0597]: `y` does not live long enough
--> $DIR/escape-upvar-ref.rs:23:35
|
LL | let y = 22;
| - binding `y` declared here
LL | let mut closure = || p = &y;
| -- ^ borrowed value does not live long enough
| |

View File

@ -1,6 +1,8 @@
error[E0597]: `local_arr` does not live long enough
--> $DIR/propagate-multiple-requirements.rs:15:14
|
LL | let local_arr = other_local_arr;
| --------- binding `local_arr` declared here
LL | let mut out: &mut &'static [i32] = &mut (&[1] as _);
| ------------------- type annotation requires that `local_arr` is borrowed for `'static`
LL | once(|mut z: &[i32], mut out_val: &mut &[i32]| {

View File

@ -32,7 +32,10 @@ note: if `S<Box<u32>>` implemented `Clone`, you could clone the value
--> $DIR/issue-21232-partial-init-and-use.rs:15:1
|
LL | struct S<Y> {
| ^^^^^^^^^^^
| ^^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | let mut s: S<B> = S::new(); drop(s);
| - you could clone this value
error[E0382]: assign to part of moved value: `t`
--> $DIR/issue-21232-partial-init-and-use.rs:116:5
@ -83,7 +86,10 @@ note: if `S<Box<u32>>` implemented `Clone`, you could clone the value
--> $DIR/issue-21232-partial-init-and-use.rs:15:1
|
LL | struct S<Y> {
| ^^^^^^^^^^^
| ^^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | let mut s: S<B> = S::new(); drop(s);
| - you could clone this value
error[E0382]: assign to part of moved value: `t`
--> $DIR/issue-21232-partial-init-and-use.rs:142:5

View File

@ -0,0 +1,23 @@
// Issue 27282: Example 1: This sidesteps the AST checks disallowing
// mutable borrows in match guards by hiding the mutable borrow in a
// guard behind a move (of the ref mut pattern id) within a closure.
//@ run-rustfix
#![feature(if_let_guard)]
fn main() {
match Some(&4) {
None => {},
ref mut foo
if { (|| { let mut bar = foo.clone(); bar.take() })(); false } => {},
//~^ ERROR cannot move out of `foo` in pattern guard [E0507]
Some(s) => std::process::exit(*s),
}
match Some(&4) {
None => {},
ref mut foo
if let Some(()) = { (|| { let mut bar = foo.clone(); bar.take() })(); None } => {},
//~^ ERROR cannot move out of `foo` in pattern guard [E0507]
Some(s) => std::process::exit(*s),
}
}

View File

@ -1,14 +1,14 @@
// Issue 27282: Example 1: This sidesteps the AST checks disallowing
// mutable borrows in match guards by hiding the mutable borrow in a
// guard behind a move (of the ref mut pattern id) within a closure.
//@ run-rustfix
#![feature(if_let_guard)]
fn main() {
match Some(&4) {
None => {},
ref mut foo
if { (|| { let bar = foo; bar.take() })(); false } => {},
if { (|| { let mut bar = foo; bar.take() })(); false } => {},
//~^ ERROR cannot move out of `foo` in pattern guard [E0507]
Some(s) => std::process::exit(*s),
}
@ -16,7 +16,7 @@ fn main() {
match Some(&4) {
None => {},
ref mut foo
if let Some(()) = { (|| { let bar = foo; bar.take() })(); None } => {},
if let Some(()) = { (|| { let mut bar = foo; bar.take() })(); None } => {},
//~^ ERROR cannot move out of `foo` in pattern guard [E0507]
Some(s) => std::process::exit(*s),
}

View File

@ -1,22 +1,30 @@
error[E0507]: cannot move out of `foo` in pattern guard
--> $DIR/issue-27282-move-ref-mut-into-guard.rs:11:19
|
LL | if { (|| { let bar = foo; bar.take() })(); false } => {},
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
LL | if { (|| { let mut bar = foo; bar.take() })(); false } => {},
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
| |
| `foo` is moved here
|
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
help: consider cloning the value if the performance cost is acceptable
|
LL | if { (|| { let mut bar = foo.clone(); bar.take() })(); false } => {},
| ++++++++
error[E0507]: cannot move out of `foo` in pattern guard
--> $DIR/issue-27282-move-ref-mut-into-guard.rs:19:34
|
LL | if let Some(()) = { (|| { let bar = foo; bar.take() })(); None } => {},
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
LL | if let Some(()) = { (|| { let mut bar = foo; bar.take() })(); None } => {},
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
| |
| `foo` is moved here
|
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
help: consider cloning the value if the performance cost is acceptable
|
LL | if let Some(()) = { (|| { let mut bar = foo.clone(); bar.take() })(); None } => {},
| ++++++++
error: aborting due to 2 previous errors

View File

@ -7,6 +7,10 @@ LL | (|| { let bar = foo; bar.take() })();
| `foo` is moved here
|
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
help: consider cloning the value if the performance cost is acceptable
|
LL | (|| { let bar = foo.clone(); bar.take() })();
| ++++++++
error[E0507]: cannot move out of `foo` in pattern guard
--> $DIR/issue-27282-mutation-in-guard.rs:20:18
@ -17,6 +21,10 @@ LL | (|| { let bar = foo; bar.take() })();
| `foo` is moved here
|
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
help: consider cloning the value if the performance cost is acceptable
|
LL | (|| { let bar = foo.clone(); bar.take() })();
| ++++++++
error: aborting due to 2 previous errors

View File

@ -11,6 +11,8 @@ LL | || doit(data);
error[E0597]: `data` does not live long enough
--> $DIR/issue-42574-diagnostic-in-nested-closure.rs:6:13
|
LL | fn doit(data: &'static mut ()) {
| ---- binding `data` declared here
LL | || doit(data);
| -- -----^^^^-
| | | |

View File

@ -0,0 +1,66 @@
#![feature(if_let_guard)]
#![allow(unused_mut)]
//@ run-rustfix
// Here is arielb1's basic example from rust-lang/rust#27282
// that AST borrowck is flummoxed by:
fn should_reject_destructive_mutate_in_guard() {
match Some(&4) {
None => {},
ref mut foo if {
(|| { let mut bar = foo.clone(); bar.take() })();
//~^ ERROR cannot move out of `foo` in pattern guard [E0507]
false } => { },
Some(s) => std::process::exit(*s),
}
match Some(&4) {
None => {},
ref mut foo if let Some(()) = {
(|| { let mut bar = foo.clone(); bar.take() })();
//~^ ERROR cannot move out of `foo` in pattern guard [E0507]
None } => { },
Some(s) => std::process::exit(*s),
}
}
// Here below is a case that needs to keep working: we only use the
// binding via immutable-borrow in the guard, and we mutate in the arm
// body.
fn allow_mutate_in_arm_body() {
match Some(&4) {
None => {},
ref mut foo if foo.is_some() => { foo.take(); () }
Some(s) => std::process::exit(*s),
}
match Some(&4) {
None => {},
ref mut foo if let Some(_) = foo => { foo.take(); () }
Some(s) => std::process::exit(*s),
}
}
// Here below is a case that needs to keep working: we only use the
// binding via immutable-borrow in the guard, and we move into the arm
// body.
fn allow_move_into_arm_body() {
match Some(&4) {
None => {},
mut foo if foo.is_some() => { foo.unwrap(); () }
Some(s) => std::process::exit(*s),
}
match Some(&4) {
None => {},
mut foo if let Some(_) = foo => { foo.unwrap(); () }
Some(s) => std::process::exit(*s),
}
}
fn main() {
should_reject_destructive_mutate_in_guard();
allow_mutate_in_arm_body();
allow_move_into_arm_body();
}

View File

@ -1,4 +1,6 @@
#![feature(if_let_guard)]
#![allow(unused_mut)]
//@ run-rustfix
// Here is arielb1's basic example from rust-lang/rust#27282
// that AST borrowck is flummoxed by:
@ -7,7 +9,7 @@ fn should_reject_destructive_mutate_in_guard() {
match Some(&4) {
None => {},
ref mut foo if {
(|| { let bar = foo; bar.take() })();
(|| { let mut bar = foo; bar.take() })();
//~^ ERROR cannot move out of `foo` in pattern guard [E0507]
false } => { },
Some(s) => std::process::exit(*s),
@ -16,7 +18,7 @@ fn should_reject_destructive_mutate_in_guard() {
match Some(&4) {
None => {},
ref mut foo if let Some(()) = {
(|| { let bar = foo; bar.take() })();
(|| { let mut bar = foo; bar.take() })();
//~^ ERROR cannot move out of `foo` in pattern guard [E0507]
None } => { },
Some(s) => std::process::exit(*s),

View File

@ -1,22 +1,30 @@
error[E0507]: cannot move out of `foo` in pattern guard
--> $DIR/match-guards-always-borrow.rs:10:14
--> $DIR/match-guards-always-borrow.rs:12:14
|
LL | (|| { let bar = foo; bar.take() })();
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
LL | (|| { let mut bar = foo; bar.take() })();
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
| |
| `foo` is moved here
|
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
help: consider cloning the value if the performance cost is acceptable
|
LL | (|| { let mut bar = foo.clone(); bar.take() })();
| ++++++++
error[E0507]: cannot move out of `foo` in pattern guard
--> $DIR/match-guards-always-borrow.rs:19:14
--> $DIR/match-guards-always-borrow.rs:21:14
|
LL | (|| { let bar = foo; bar.take() })();
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
LL | (|| { let mut bar = foo; bar.take() })();
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
| |
| `foo` is moved here
|
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
help: consider cloning the value if the performance cost is acceptable
|
LL | (|| { let mut bar = foo.clone(); bar.take() })();
| ++++++++
error: aborting due to 2 previous errors

View File

@ -8,7 +8,10 @@ note: if `A` implemented `Clone`, you could clone the value
--> $DIR/move-errors.rs:1:1
|
LL | struct A(String);
| ^^^^^^^^
| ^^^^^^^^ consider implementing `Clone` for this type
...
LL | let b = *a;
| -- you could clone this value
help: consider removing the dereference here
|
LL - let b = *a;
@ -28,7 +31,10 @@ note: if `A` implemented `Clone`, you could clone the value
--> $DIR/move-errors.rs:1:1
|
LL | struct A(String);
| ^^^^^^^^
| ^^^^^^^^ consider implementing `Clone` for this type
...
LL | let b = a[0];
| ---- you could clone this value
help: consider borrowing here
|
LL | let b = &a[0];
@ -44,7 +50,10 @@ note: if `A` implemented `Clone`, you could clone the value
--> $DIR/move-errors.rs:1:1
|
LL | struct A(String);
| ^^^^^^^^
| ^^^^^^^^ consider implementing `Clone` for this type
...
LL | let s = **r;
| --- you could clone this value
help: consider removing the dereference here
|
LL - let s = **r;
@ -61,7 +70,10 @@ note: if `A` implemented `Clone`, you could clone the value
--> $DIR/move-errors.rs:1:1
|
LL | struct A(String);
| ^^^^^^^^
| ^^^^^^^^ consider implementing `Clone` for this type
...
LL | let s = *r;
| -- you could clone this value
help: consider removing the dereference here
|
LL - let s = *r;
@ -81,7 +93,10 @@ note: if `A` implemented `Clone`, you could clone the value
--> $DIR/move-errors.rs:1:1
|
LL | struct A(String);
| ^^^^^^^^
| ^^^^^^^^ consider implementing `Clone` for this type
...
LL | let a = [A("".to_string())][0];
| ---------------------- you could clone this value
help: consider borrowing here
|
LL | let a = &[A("".to_string())][0];
@ -126,7 +141,10 @@ note: if `A` implemented `Clone`, you could clone the value
--> $DIR/move-errors.rs:1:1
|
LL | struct A(String);
| ^^^^^^^^
| ^^^^^^^^ consider implementing `Clone` for this type
...
LL | b = *a;
| -- you could clone this value
error[E0508]: cannot move out of type `[B; 1]`, a non-copy array
--> $DIR/move-errors.rs:74:11

View File

@ -1,6 +1,8 @@
error[E0597]: `a` does not live long enough
--> $DIR/location-insensitive-scopes-issue-117146.rs:10:18
|
LL | let a = ();
| - binding `a` declared here
LL | let b = |_| &a;
| --- -^
| | ||

View File

@ -1,6 +1,8 @@
error[E0597]: `a` does not live long enough
--> $DIR/location-insensitive-scopes-issue-117146.rs:10:18
|
LL | let a = ();
| - binding `a` declared here
LL | let b = |_| &a;
| --- -^
| | ||

View File

@ -33,7 +33,9 @@ error[E0597]: `a` does not live long enough
|
LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
| -- lifetime `'a` defined here
...
LL | let a = 22;
| - binding `a` declared here
LL | let b = 44;
LL | let _closure = || {
| -- value captured here
LL | let c = 66;

View File

@ -34,7 +34,9 @@ error[E0597]: `b` does not live long enough
|
LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
| -- lifetime `'a` defined here
...
LL | let a = 22;
LL | let b = 44;
| - binding `b` declared here
LL | let _closure = || {
| -- value captured here
LL | let c = 66;

View File

@ -337,7 +337,10 @@ note: if `U` implemented `Clone`, you could clone the value
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:17:5
|
LL | struct U;
| ^^^^^^^^
| ^^^^^^^^ consider implementing `Clone` for this type
...
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
| - you could clone this value
error[E0507]: cannot move out of `b` in pattern guard
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:66
@ -350,7 +353,10 @@ note: if `U` implemented `Clone`, you could clone the value
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:17:5
|
LL | struct U;
| ^^^^^^^^
| ^^^^^^^^ consider implementing `Clone` for this type
...
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
| - you could clone this value
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0507]: cannot move out of `a` in pattern guard

View File

@ -20,6 +20,8 @@ LL | let p: &'static mut usize = &mut self.food;
error[E0597]: `self` does not live long enough
--> $DIR/regions-addr-of-upvar-self.rs:8:46
|
LL | pub fn chase_cat(&mut self) {
| --------- binding `self` declared here
LL | let _f = || {
| -- value captured here
LL | let p: &'static mut usize = &mut self.food;

View File

@ -1,6 +1,9 @@
error[E0597]: `y` does not live long enough
--> $DIR/regions-nested-fns-2.rs:7:25
|
LL | let y = 3;
| - binding `y` declared here
LL | ignore(
LL | |z| {
| --- value captured here
LL | if false { &y } else { z }

View File

@ -27,6 +27,9 @@ LL | }
error[E0597]: `y` does not live long enough
--> $DIR/regions-nested-fns.rs:10:15
|
LL | let y = 3;
| - binding `y` declared here
...
LL | ignore::<Box<dyn for<'z> FnMut(&'z isize)>>(Box::new(|z| {
| --- value captured here
LL | ay = x;

View File

@ -4,6 +4,7 @@ error[E0597]: `i` does not live long enough
LL | let mut cl_box = {
| ---------- borrow later stored here
LL | let mut i = 3;
| ----- binding `i` declared here
LL | box_it(Box::new(|| i += 1))
| -- ^ borrowed value does not live long enough
| |

View File

@ -16,6 +16,9 @@ error[E0597]: `y` does not live long enough
|
LL | let bad = {
| --- borrow later stored here
LL | let x = 1;
LL | let y = &x;
| - binding `y` declared here
...
LL | scoped(|| {
| -- value captured here

View File

@ -1,8 +1,10 @@
struct NotCopyable;
#[derive(Clone)]
struct NotCopyableButCloneable;
fn func<F: FnMut() -> H, H: FnMut()>(_: F) {}
fn parse() {
fn foo() {
let mut var = None;
func(|| {
// Shouldn't suggest `move ||.as_ref()` here
@ -12,5 +14,15 @@ fn parse() {
}
});
}
fn bar() {
let mut var = None;
func(|| {
// Shouldn't suggest `move ||.as_ref()` nor to `clone()` here
move || {
//~^ ERROR: cannot move out of `var`
var = Some(NotCopyableButCloneable);
}
});
}
fn main() {}

View File

@ -1,5 +1,5 @@
error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure
--> $DIR/option-content-move2.rs:9:9
--> $DIR/option-content-move2.rs:11:9
|
LL | let mut var = None;
| ------- captured outer variable
@ -15,6 +15,23 @@ LL | var = Some(NotCopyable);
| variable moved due to use in closure
| move occurs because `var` has type `Option<NotCopyable>`, which does not implement the `Copy` trait
error: aborting due to 1 previous error
error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure
--> $DIR/option-content-move2.rs:21:9
|
LL | let mut var = None;
| ------- captured outer variable
LL | func(|| {
| -- captured by this `FnMut` closure
LL | // Shouldn't suggest `move ||.as_ref()` nor to `clone()` here
LL | move || {
| ^^^^^^^ `var` is moved here
LL |
LL | var = Some(NotCopyableButCloneable);
| ---
| |
| variable moved due to use in closure
| move occurs because `var` has type `Option<NotCopyableButCloneable>`, which does not implement the `Copy` trait
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0507`.

View File

@ -0,0 +1,30 @@
#[derive(Debug)]
struct NotCopyable;
#[derive(Debug, Clone)]
struct NotCopyableButCloneable;
fn func<F: FnMut() -> H, H: FnMut()>(_: F) {}
fn foo() {
let var = NotCopyable;
func(|| {
// Shouldn't suggest `move ||.as_ref()` here
move || { //~ ERROR cannot move out of `var`
let x = var; //~ ERROR cannot move out of `var`
println!("{x:?}");
}
});
}
fn bar() {
let var = NotCopyableButCloneable;
func(|| {
// Shouldn't suggest `move ||.as_ref()` here
move || { //~ ERROR cannot move out of `var`
let x = var; //~ ERROR cannot move out of `var`
println!("{x:?}");
}
});
}
fn main() {}

View File

@ -0,0 +1,95 @@
error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure
--> $DIR/option-content-move3.rs:13:21
|
LL | let var = NotCopyable;
| --- captured outer variable
...
LL | move || {
| ------- captured by this `FnMut` closure
LL | let x = var;
| ^^^ move occurs because `var` has type `NotCopyable`, which does not implement the `Copy` trait
|
note: if `NotCopyable` implemented `Clone`, you could clone the value
--> $DIR/option-content-move3.rs:2:1
|
LL | struct NotCopyable;
| ^^^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | let x = var;
| --- you could clone this value
help: consider borrowing here
|
LL | let x = &var;
| +
error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure
--> $DIR/option-content-move3.rs:12:9
|
LL | let var = NotCopyable;
| --- captured outer variable
LL | func(|| {
| -- captured by this `FnMut` closure
LL | // Shouldn't suggest `move ||.as_ref()` here
LL | move || {
| ^^^^^^^ `var` is moved here
LL | let x = var;
| ---
| |
| variable moved due to use in closure
| move occurs because `var` has type `NotCopyable`, which does not implement the `Copy` trait
|
note: if `NotCopyable` implemented `Clone`, you could clone the value
--> $DIR/option-content-move3.rs:2:1
|
LL | struct NotCopyable;
| ^^^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | let x = var;
| --- you could clone this value
error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure
--> $DIR/option-content-move3.rs:24:21
|
LL | let var = NotCopyableButCloneable;
| --- captured outer variable
...
LL | move || {
| ------- captured by this `FnMut` closure
LL | let x = var;
| ^^^ move occurs because `var` has type `NotCopyableButCloneable`, which does not implement the `Copy` trait
|
help: consider borrowing here
|
LL | let x = &var;
| +
error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure
--> $DIR/option-content-move3.rs:23:9
|
LL | let var = NotCopyableButCloneable;
| --- captured outer variable
LL | func(|| {
| -- captured by this `FnMut` closure
LL | // Shouldn't suggest `move ||.as_ref()` here
LL | move || {
| ^^^^^^^ `var` is moved here
LL | let x = var;
| ---
| |
| variable moved due to use in closure
| move occurs because `var` has type `NotCopyableButCloneable`, which does not implement the `Copy` trait
|
help: clone the value before moving it into the closure
|
LL ~ {
LL + let value = var.clone();
LL ~ move || {
LL ~ let x = value;
LL | println!("{x:?}");
LL ~ }
LL + }
|
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0507`.

View File

@ -1,6 +1,9 @@
error[E0597]: `factorial` does not live long enough
--> $DIR/unboxed-closures-failed-recursive-fn-1.rs:15:17
|
LL | let mut factorial: Option<Box<dyn Fn(u32) -> u32>> = None;
| ------------- binding `factorial` declared here
LL |
LL | let f = |x: u32| -> u32 {
| --------------- value captured here
LL | let g = factorial.as_ref().unwrap();
@ -30,7 +33,9 @@ error[E0597]: `factorial` does not live long enough
--> $DIR/unboxed-closures-failed-recursive-fn-1.rs:28:17
|
LL | let mut factorial: Option<Box<dyn Fn(u32) -> u32 + 'static>> = None;
| ----------------------------------------- type annotation requires that `factorial` is borrowed for `'static`
| ------------- ----------------------------------------- type annotation requires that `factorial` is borrowed for `'static`
| |
| binding `factorial` declared here
LL |
LL | let f = |x: u32| -> u32 {
| --------------- value captured here

View File

@ -54,7 +54,10 @@ note: if `MockVec<u8>` implemented `Clone`, you could clone the value
--> $DIR/union-borrow-move-parent-sibling.rs:25:1
|
LL | struct MockVec<T> {
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | let a = (u.x.0).0;
| --------- you could clone this value
help: consider borrowing here
|
LL | let a = &(u.x.0).0;

View File

@ -20,7 +20,10 @@ note: if `U1` implemented `Clone`, you could clone the value
--> $DIR/union-move.rs:9:1
|
LL | union U1 {
| ^^^^^^^^
| ^^^^^^^^ consider implementing `Clone` for this type
...
LL | move_out(x.f1_nocopy);
| ----------- you could clone this value
error[E0382]: use of moved value: `x`
--> $DIR/union-move.rs:42:18
@ -44,7 +47,10 @@ note: if `U1` implemented `Clone`, you could clone the value
--> $DIR/union-move.rs:9:1
|
LL | union U1 {
| ^^^^^^^^
| ^^^^^^^^ consider implementing `Clone` for this type
...
LL | move_out(x.f2_nocopy);
| ----------- you could clone this value
error[E0509]: cannot move out of type `U2`, which implements the `Drop` trait
--> $DIR/union-move.rs:49:18

View File

@ -33,6 +33,14 @@ LL | !x;
...
LL | use_mut(n); use_imm(m);
| - borrow later used here
|
help: if `T` implemented `Clone`, you could clone the value
--> $DIR/unop-move-semantics.rs:11:18
|
LL | fn move_borrowed<T: Not<Output=T>>(x: T, mut y: T) {
| ^ consider constraining this type parameter with `Clone`
LL | let m = &x;
| -- you could clone this value
error[E0505]: cannot move out of `y` because it is borrowed
--> $DIR/unop-move-semantics.rs:17:6
@ -47,6 +55,15 @@ LL | !y;
| ^ move out of `y` occurs here
LL | use_mut(n); use_imm(m);
| - borrow later used here
|
help: if `T` implemented `Clone`, you could clone the value
--> $DIR/unop-move-semantics.rs:11:18
|
LL | fn move_borrowed<T: Not<Output=T>>(x: T, mut y: T) {
| ^ consider constraining this type parameter with `Clone`
LL | let m = &x;
LL | let n = &mut y;
| ------ you could clone this value
error[E0507]: cannot move out of `*m` which is behind a mutable reference
--> $DIR/unop-move-semantics.rs:24:6
@ -59,6 +76,14 @@ LL | !*m;
|
note: calling this operator moves the value
--> $SRC_DIR/core/src/ops/bit.rs:LL:COL
help: if `T` implemented `Clone`, you could clone the value
--> $DIR/unop-move-semantics.rs:20:24
|
LL | fn illegal_dereference<T: Not<Output=T>>(mut x: T, y: T) {
| ^ consider constraining this type parameter with `Clone`
...
LL | !*m;
| -- you could clone this value
error[E0507]: cannot move out of `*n` which is behind a shared reference
--> $DIR/unop-move-semantics.rs:26:6
@ -68,6 +93,15 @@ LL | !*n;
| ||
| |move occurs because `*n` has type `T`, which does not implement the `Copy` trait
| `*n` moved due to usage in operator
|
help: if `T` implemented `Clone`, you could clone the value
--> $DIR/unop-move-semantics.rs:20:24
|
LL | fn illegal_dereference<T: Not<Output=T>>(mut x: T, y: T) {
| ^ consider constraining this type parameter with `Clone`
...
LL | !*n;
| -- you could clone this value
error: aborting due to 5 previous errors

View File

@ -14,7 +14,10 @@ note: if `AffineU32` implemented `Clone`, you could clone the value
--> $DIR/variance-issue-20533.rs:26:1
|
LL | struct AffineU32(u32);
| ^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | let x = foo(&a);
| -- you could clone this value
error[E0505]: cannot move out of `a` because it is borrowed
--> $DIR/variance-issue-20533.rs:41:14
@ -32,7 +35,10 @@ note: if `AffineU32` implemented `Clone`, you could clone the value
--> $DIR/variance-issue-20533.rs:26:1
|
LL | struct AffineU32(u32);
| ^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | let x = bar(&a);
| -- you could clone this value
error[E0505]: cannot move out of `a` because it is borrowed
--> $DIR/variance-issue-20533.rs:47:14
@ -50,7 +56,10 @@ note: if `AffineU32` implemented `Clone`, you could clone the value
--> $DIR/variance-issue-20533.rs:26:1
|
LL | struct AffineU32(u32);
| ^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | let x = baz(&a);
| -- you could clone this value
error[E0505]: cannot move out of `a` because it is borrowed
--> $DIR/variance-issue-20533.rs:53:14