From 86dd457e6a595f7a7fd55ebfda530e20cca478f4 Mon Sep 17 00:00:00 2001 From: Obei Sideg Date: Sat, 23 Jul 2022 00:35:35 +0300 Subject: [PATCH] Improve `cannot move out of` error message --- .../src/diagnostics/conflict_errors.rs | 30 +++++--- .../rustc_borrowck/src/diagnostics/mod.rs | 74 ++++++++++++++----- .../src/diagnostics/move_errors.rs | 28 +++++-- .../borrowck/access-mode-in-closures.stderr | 2 +- .../borrowck-move-error-with-note.stderr | 2 +- .../ui/moves/issue-99470-move-out-of-some.rs | 9 +++ .../moves/issue-99470-move-out-of-some.stderr | 16 ++++ .../moves-based-on-type-block-bad.stderr | 2 +- src/test/ui/nll/move-errors.stderr | 4 +- .../dont-suggest-ref/simple.stderr | 48 ++++++------ 10 files changed, 154 insertions(+), 61 deletions(-) create mode 100644 src/test/ui/moves/issue-99470-move-out-of-some.rs create mode 100644 src/test/ui/moves/issue-99470-move-out-of-some.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index eae162fe479..5da260f980f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -39,7 +39,7 @@ use super::{ explain_borrow::{BorrowExplanation, LaterUseKind}, - IncludingDowncast, RegionName, RegionNameSource, UseSpans, + DescribePlaceOpt, RegionName, RegionNameSource, UseSpans, }; #[derive(Debug)] @@ -137,7 +137,10 @@ pub(crate) fn report_use_of_moved_or_uninitialized( span, desired_action.as_noun(), partially_str, - self.describe_place_with_options(moved_place, IncludingDowncast(true)), + self.describe_place_with_options( + moved_place, + DescribePlaceOpt { including_downcast: true, including_tuple_field: true }, + ), ); let reinit_spans = maybe_reinitialized_locations @@ -274,8 +277,10 @@ pub(crate) fn report_use_of_moved_or_uninitialized( } } - let opt_name = - self.describe_place_with_options(place.as_ref(), IncludingDowncast(true)); + let opt_name = self.describe_place_with_options( + place.as_ref(), + DescribePlaceOpt { including_downcast: true, including_tuple_field: true }, + ); let note_msg = match opt_name { Some(ref name) => format!("`{}`", name), None => "value".to_owned(), @@ -341,12 +346,17 @@ fn report_use_of_uninitialized( } } - let (name, desc) = - match self.describe_place_with_options(moved_place, IncludingDowncast(true)) { - Some(name) => (format!("`{name}`"), format!("`{name}` ")), - None => ("the variable".to_string(), String::new()), - }; - let path = match self.describe_place_with_options(used_place, IncludingDowncast(true)) { + let (name, desc) = match self.describe_place_with_options( + moved_place, + DescribePlaceOpt { including_downcast: true, including_tuple_field: true }, + ) { + Some(name) => (format!("`{name}`"), format!("`{name}` ")), + None => ("the variable".to_string(), String::new()), + }; + let path = match self.describe_place_with_options( + used_place, + DescribePlaceOpt { including_downcast: true, including_tuple_field: true }, + ) { Some(name) => format!("`{name}`"), None => "value".to_string(), }; diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 0300180f80a..098e8de9420 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -4,7 +4,7 @@ use rustc_const_eval::util::{call_kind, CallDesugaringKind}; use rustc_errors::{Applicability, Diagnostic}; use rustc_hir as hir; -use rustc_hir::def::Namespace; +use rustc_hir::def::{CtorKind, Namespace}; use rustc_hir::GeneratorKind; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::tcx::PlaceTy; @@ -16,7 +16,7 @@ use rustc_middle::ty::{self, DefIdTree, Instance, Ty, TyCtxt}; use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult}; use rustc_span::def_id::LocalDefId; -use rustc_span::{symbol::sym, Span, DUMMY_SP}; +use rustc_span::{symbol::sym, Span, Symbol, DUMMY_SP}; use rustc_target::abi::VariantIdx; use rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions; @@ -43,7 +43,15 @@ pub(crate) use region_name::{RegionName, RegionNameSource}; pub(crate) use rustc_const_eval::util::CallKind; -pub(super) struct IncludingDowncast(pub(super) bool); +pub(super) struct DescribePlaceOpt { + pub including_downcast: bool, + + /// Enable/Disable tuple fields. + /// For example `x` tuple. if it's `true` `x.0`. Otherwise `x` + pub including_tuple_field: bool, +} + +pub(super) struct IncludingTupleField(pub(super) bool); impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// Adds a suggestion when a closure is invoked twice with a moved variable or when a closure @@ -164,7 +172,10 @@ pub(super) fn describe_any_place(&self, place_ref: PlaceRef<'tcx>) -> String { /// End-user visible description of `place` if one can be found. /// If the place is a temporary for instance, `None` will be returned. pub(super) fn describe_place(&self, place_ref: PlaceRef<'tcx>) -> Option { - self.describe_place_with_options(place_ref, IncludingDowncast(false)) + self.describe_place_with_options( + place_ref, + DescribePlaceOpt { including_downcast: false, including_tuple_field: true }, + ) } /// End-user visible description of `place` if one can be found. If the place is a temporary @@ -174,7 +185,7 @@ pub(super) fn describe_place(&self, place_ref: PlaceRef<'tcx>) -> Option pub(super) fn describe_place_with_options( &self, place: PlaceRef<'tcx>, - including_downcast: IncludingDowncast, + opt: DescribePlaceOpt, ) -> Option { let local = place.local; let mut autoderef_index = None; @@ -224,7 +235,7 @@ pub(super) fn describe_place_with_options( } } } - ProjectionElem::Downcast(..) if including_downcast.0 => return None, + ProjectionElem::Downcast(..) if opt.including_downcast => return None, ProjectionElem::Downcast(..) => (), ProjectionElem::Field(field, _ty) => { // FIXME(project-rfc_2229#36): print capture precisely here. @@ -238,9 +249,12 @@ pub(super) fn describe_place_with_options( let field_name = self.describe_field( PlaceRef { local, projection: place.projection.split_at(index).0 }, *field, + IncludingTupleField(opt.including_tuple_field), ); - buf.push('.'); - buf.push_str(&field_name); + if let Some(field_name_str) = field_name { + buf.push('.'); + buf.push_str(&field_name_str); + } } } ProjectionElem::Index(index) => { @@ -261,6 +275,18 @@ pub(super) fn describe_place_with_options( ok.ok().map(|_| buf) } + fn describe_name(&self, place: PlaceRef<'tcx>) -> Option { + for elem in place.projection.into_iter() { + match elem { + ProjectionElem::Downcast(Some(name), _) => { + return Some(*name); + } + _ => {} + } + } + None + } + /// Appends end-user visible description of the `local` place to `buf`. If `local` doesn't have /// a name, or its name was generated by the compiler, then `Err` is returned fn append_local_to_string(&self, local: Local, buf: &mut String) -> Result<(), ()> { @@ -275,7 +301,12 @@ fn append_local_to_string(&self, local: Local, buf: &mut String) -> Result<(), ( } /// End-user visible description of the `field`nth field of `base` - fn describe_field(&self, place: PlaceRef<'tcx>, field: Field) -> String { + fn describe_field( + &self, + place: PlaceRef<'tcx>, + field: Field, + including_tuple_field: IncludingTupleField, + ) -> Option { let place_ty = match place { PlaceRef { local, projection: [] } => PlaceTy::from_ty(self.body.local_decls[local].ty), PlaceRef { local, projection: [proj_base @ .., elem] } => match elem { @@ -289,7 +320,12 @@ fn describe_field(&self, place: PlaceRef<'tcx>, field: Field) -> String { ProjectionElem::Field(_, field_type) => PlaceTy::from_ty(*field_type), }, }; - self.describe_field_from_ty(place_ty.ty, field, place_ty.variant_index) + self.describe_field_from_ty( + place_ty.ty, + field, + place_ty.variant_index, + including_tuple_field, + ) } /// End-user visible description of the `field_index`nth field of `ty` @@ -298,10 +334,11 @@ fn describe_field_from_ty( ty: Ty<'_>, field: Field, variant_index: Option, - ) -> String { + including_tuple_field: IncludingTupleField, + ) -> Option { if ty.is_box() { // If the type is a box, the field is described from the boxed type - self.describe_field_from_ty(ty.boxed_ty(), field, variant_index) + self.describe_field_from_ty(ty.boxed_ty(), field, variant_index, including_tuple_field) } else { match *ty.kind() { ty::Adt(def, _) => { @@ -311,14 +348,17 @@ fn describe_field_from_ty( } else { def.non_enum_variant() }; - variant.fields[field.index()].name.to_string() + if !including_tuple_field.0 && variant.ctor_kind == CtorKind::Fn { + return None; + } + Some(variant.fields[field.index()].name.to_string()) } - ty::Tuple(_) => field.index().to_string(), + ty::Tuple(_) => Some(field.index().to_string()), ty::Ref(_, ty, _) | ty::RawPtr(ty::TypeAndMut { ty, .. }) => { - self.describe_field_from_ty(ty, field, variant_index) + self.describe_field_from_ty(ty, field, variant_index, including_tuple_field) } ty::Array(ty, _) | ty::Slice(ty) => { - self.describe_field_from_ty(ty, field, variant_index) + self.describe_field_from_ty(ty, field, variant_index, including_tuple_field) } ty::Closure(def_id, _) | ty::Generator(def_id, _, _) => { // We won't be borrowck'ing here if the closure came from another crate, @@ -335,7 +375,7 @@ fn describe_field_from_ty( .unwrap() .get_root_variable(); - self.infcx.tcx.hir().name(var_id).to_string() + Some(self.infcx.tcx.hir().name(var_id).to_string()) } _ => { // Might need a revision when the fields in trait RFC is implemented diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index becb81b2e26..cb3cd479ae2 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -6,7 +6,7 @@ }; use rustc_span::Span; -use crate::diagnostics::UseSpans; +use crate::diagnostics::{DescribePlaceOpt, UseSpans}; use crate::prefixes::PrefixSet; use crate::MirBorrowckCtxt; @@ -368,13 +368,31 @@ fn report_cannot_move_from_borrowed_content( } _ => { let source = self.borrowed_content_source(deref_base); - match (self.describe_place(move_place.as_ref()), source.describe_for_named_place()) - { - (Some(place_desc), Some(source_desc)) => self.cannot_move_out_of( + let move_place_ref = move_place.as_ref(); + match ( + self.describe_place_with_options( + move_place_ref, + DescribePlaceOpt { + including_downcast: false, + including_tuple_field: false, + }, + ), + self.describe_name(move_place_ref), + source.describe_for_named_place(), + ) { + (Some(place_desc), Some(name), Some(source_desc)) => self.cannot_move_out_of( + span, + &format!("`{place_desc}` as enum variant `{name}` which is behind a {source_desc}"), + ), + (Some(place_desc), Some(name), None) => self.cannot_move_out_of( + span, + &format!("`{place_desc}` as enum variant `{name}`"), + ), + (Some(place_desc), _, Some(source_desc)) => self.cannot_move_out_of( span, &format!("`{place_desc}` which is behind a {source_desc}"), ), - (_, _) => self.cannot_move_out_of( + (_, _, _) => self.cannot_move_out_of( span, &source.describe_for_unnamed_place(self.infcx.tcx), ), diff --git a/src/test/ui/borrowck/access-mode-in-closures.stderr b/src/test/ui/borrowck/access-mode-in-closures.stderr index c32e944afe3..13a6277da14 100644 --- a/src/test/ui/borrowck/access-mode-in-closures.stderr +++ b/src/test/ui/borrowck/access-mode-in-closures.stderr @@ -1,4 +1,4 @@ -error[E0507]: cannot move out of `s.0` which is behind a shared reference +error[E0507]: cannot move out of `s` which is behind a shared reference --> $DIR/access-mode-in-closures.rs:8:15 | LL | match *s { S(v) => v } diff --git a/src/test/ui/borrowck/borrowck-move-error-with-note.stderr b/src/test/ui/borrowck/borrowck-move-error-with-note.stderr index ead02414a62..96246d9ae1a 100644 --- a/src/test/ui/borrowck/borrowck-move-error-with-note.stderr +++ b/src/test/ui/borrowck/borrowck-move-error-with-note.stderr @@ -1,4 +1,4 @@ -error[E0507]: cannot move out of `f.0` which is behind a shared reference +error[E0507]: cannot move out of `f` as enum variant `Foo1` which is behind a shared reference --> $DIR/borrowck-move-error-with-note.rs:11:11 | LL | match *f { diff --git a/src/test/ui/moves/issue-99470-move-out-of-some.rs b/src/test/ui/moves/issue-99470-move-out-of-some.rs new file mode 100644 index 00000000000..f404cd3cd71 --- /dev/null +++ b/src/test/ui/moves/issue-99470-move-out-of-some.rs @@ -0,0 +1,9 @@ +fn main() { + let x: &Option> = &Some(Box::new(0)); + + match x { + //~^ ERROR cannot move out of `x` as enum variant `Some` which is behind a shared reference + &Some(_y) => (), + &None => (), + } +} diff --git a/src/test/ui/moves/issue-99470-move-out-of-some.stderr b/src/test/ui/moves/issue-99470-move-out-of-some.stderr new file mode 100644 index 00000000000..6e4a4e5ba22 --- /dev/null +++ b/src/test/ui/moves/issue-99470-move-out-of-some.stderr @@ -0,0 +1,16 @@ +error[E0507]: cannot move out of `x` as enum variant `Some` which is behind a shared reference + --> $DIR/issue-99470-move-out-of-some.rs:4:11 + | +LL | match x { + | ^ +LL | +LL | &Some(_y) => (), + | --------- + | | | + | | data moved here + | | move occurs because `_y` has type `Box`, which does not implement the `Copy` trait + | help: consider removing the `&`: `Some(_y)` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0507`. diff --git a/src/test/ui/moves/moves-based-on-type-block-bad.stderr b/src/test/ui/moves/moves-based-on-type-block-bad.stderr index a9ac9d63a95..5ed91a0d559 100644 --- a/src/test/ui/moves/moves-based-on-type-block-bad.stderr +++ b/src/test/ui/moves/moves-based-on-type-block-bad.stderr @@ -1,4 +1,4 @@ -error[E0507]: cannot move out of `hellothere.x.0` which is behind a shared reference +error[E0507]: cannot move out of `hellothere.x` as enum variant `Bar` which is behind a shared reference --> $DIR/moves-based-on-type-block-bad.rs:22:19 | LL | match hellothere.x { diff --git a/src/test/ui/nll/move-errors.stderr b/src/test/ui/nll/move-errors.stderr index 0df326425ad..b03fcf70bab 100644 --- a/src/test/ui/nll/move-errors.stderr +++ b/src/test/ui/nll/move-errors.stderr @@ -45,7 +45,7 @@ LL | let a = [A("".to_string())][0]; | move occurs because value has type `A`, which does not implement the `Copy` trait | help: consider borrowing here: `&[A("".to_string())][0]` -error[E0507]: cannot move out of `a.0` which is behind a shared reference +error[E0507]: cannot move out of `a` which is behind a shared reference --> $DIR/move-errors.rs:38:16 | LL | let A(s) = *a; @@ -134,7 +134,7 @@ LL | F(s, mut t) => (), | = note: move occurs because these variables have types that don't implement the `Copy` trait -error[E0507]: cannot move out of `x.0` which is behind a shared reference +error[E0507]: cannot move out of `x` as enum variant `Err` which is behind a shared reference --> $DIR/move-errors.rs:110:11 | LL | match *x { diff --git a/src/test/ui/suggestions/dont-suggest-ref/simple.stderr b/src/test/ui/suggestions/dont-suggest-ref/simple.stderr index ca09c3d5ff1..e5443290f9e 100644 --- a/src/test/ui/suggestions/dont-suggest-ref/simple.stderr +++ b/src/test/ui/suggestions/dont-suggest-ref/simple.stderr @@ -1,4 +1,4 @@ -error[E0507]: cannot move out of `s.0` which is behind a shared reference +error[E0507]: cannot move out of `s` which is behind a shared reference --> $DIR/simple.rs:38:17 | LL | let X(_t) = *s; @@ -7,7 +7,7 @@ LL | let X(_t) = *s; | data moved here | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait -error[E0507]: cannot move out of `r.0` which is behind a shared reference +error[E0507]: cannot move out of `r` as enum variant `One` which is behind a shared reference --> $DIR/simple.rs:42:30 | LL | if let Either::One(_t) = *r { } @@ -16,7 +16,7 @@ LL | if let Either::One(_t) = *r { } | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait -error[E0507]: cannot move out of `r.0` which is behind a shared reference +error[E0507]: cannot move out of `r` as enum variant `One` which is behind a shared reference --> $DIR/simple.rs:46:33 | LL | while let Either::One(_t) = *r { } @@ -25,7 +25,7 @@ LL | while let Either::One(_t) = *r { } | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait -error[E0507]: cannot move out of `r.0` which is behind a shared reference +error[E0507]: cannot move out of `r` as enum variant `Two` which is behind a shared reference --> $DIR/simple.rs:50:11 | LL | match *r { @@ -37,7 +37,7 @@ LL | Either::One(_t) | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait -error[E0507]: cannot move out of `r.0` which is behind a shared reference +error[E0507]: cannot move out of `r` as enum variant `One` which is behind a shared reference --> $DIR/simple.rs:57:11 | LL | match *r { @@ -49,7 +49,7 @@ LL | Either::One(_t) => (), | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait -error[E0507]: cannot move out of `sm.0` which is behind a mutable reference +error[E0507]: cannot move out of `sm` which is behind a mutable reference --> $DIR/simple.rs:66:17 | LL | let X(_t) = *sm; @@ -58,7 +58,7 @@ LL | let X(_t) = *sm; | data moved here | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait -error[E0507]: cannot move out of `rm.0` which is behind a mutable reference +error[E0507]: cannot move out of `rm` as enum variant `One` which is behind a mutable reference --> $DIR/simple.rs:70:30 | LL | if let Either::One(_t) = *rm { } @@ -67,7 +67,7 @@ LL | if let Either::One(_t) = *rm { } | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait -error[E0507]: cannot move out of `rm.0` which is behind a mutable reference +error[E0507]: cannot move out of `rm` as enum variant `One` which is behind a mutable reference --> $DIR/simple.rs:74:33 | LL | while let Either::One(_t) = *rm { } @@ -76,7 +76,7 @@ LL | while let Either::One(_t) = *rm { } | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait -error[E0507]: cannot move out of `rm.0` which is behind a mutable reference +error[E0507]: cannot move out of `rm` as enum variant `Two` which is behind a mutable reference --> $DIR/simple.rs:78:11 | LL | match *rm { @@ -88,7 +88,7 @@ LL | Either::One(_t) | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait -error[E0507]: cannot move out of `rm.0` which is behind a mutable reference +error[E0507]: cannot move out of `rm` as enum variant `One` which is behind a mutable reference --> $DIR/simple.rs:85:11 | LL | match *rm { @@ -100,7 +100,7 @@ LL | Either::One(_t) => (), | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait -error[E0507]: cannot move out of `rm.0` which is behind a mutable reference +error[E0507]: cannot move out of `rm` as enum variant `One` which is behind a mutable reference --> $DIR/simple.rs:93:11 | LL | match *rm { @@ -226,7 +226,7 @@ LL | Either::One(_t) => (), | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait -error[E0507]: cannot move out of `s.0` which is behind a shared reference +error[E0507]: cannot move out of `s` which is behind a shared reference --> $DIR/simple.rs:168:18 | LL | let &X(_t) = s; @@ -236,7 +236,7 @@ LL | let &X(_t) = s; | | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait | help: consider removing the `&`: `X(_t)` -error[E0507]: cannot move out of `r.0` which is behind a shared reference +error[E0507]: cannot move out of `r` as enum variant `One` which is behind a shared reference --> $DIR/simple.rs:172:31 | LL | if let &Either::One(_t) = r { } @@ -246,7 +246,7 @@ LL | if let &Either::One(_t) = r { } | | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | help: consider removing the `&`: `Either::One(_t)` -error[E0507]: cannot move out of `r.0` which is behind a shared reference +error[E0507]: cannot move out of `r` as enum variant `One` which is behind a shared reference --> $DIR/simple.rs:176:34 | LL | while let &Either::One(_t) = r { } @@ -256,7 +256,7 @@ LL | while let &Either::One(_t) = r { } | | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | help: consider removing the `&`: `Either::One(_t)` -error[E0507]: cannot move out of `r.0` which is behind a shared reference +error[E0507]: cannot move out of `r` as enum variant `Two` which is behind a shared reference --> $DIR/simple.rs:180:11 | LL | match r { @@ -276,7 +276,7 @@ LL + LL ~ | &Either::Two(_t) => (), | -error[E0507]: cannot move out of `r.0` which is behind a shared reference +error[E0507]: cannot move out of `r` as enum variant `One` which is behind a shared reference --> $DIR/simple.rs:188:11 | LL | match r { @@ -289,7 +289,7 @@ LL | &Either::One(_t) => (), | | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | help: consider removing the `&`: `Either::One(_t)` -error[E0507]: cannot move out of `r.0` which is behind a shared reference +error[E0507]: cannot move out of `r` as enum variant `One` which is behind a shared reference --> $DIR/simple.rs:195:11 | LL | match r { @@ -302,7 +302,7 @@ LL | &Either::One(_t) => (), | | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | help: consider removing the `&`: `Either::One(_t)` -error[E0507]: cannot move out of `sm.0` which is behind a mutable reference +error[E0507]: cannot move out of `sm` which is behind a mutable reference --> $DIR/simple.rs:207:22 | LL | let &mut X(_t) = sm; @@ -312,7 +312,7 @@ LL | let &mut X(_t) = sm; | | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait | help: consider removing the `&mut`: `X(_t)` -error[E0507]: cannot move out of `rm.0` which is behind a mutable reference +error[E0507]: cannot move out of `rm` as enum variant `One` which is behind a mutable reference --> $DIR/simple.rs:211:35 | LL | if let &mut Either::One(_t) = rm { } @@ -322,7 +322,7 @@ LL | if let &mut Either::One(_t) = rm { } | | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | help: consider removing the `&mut`: `Either::One(_t)` -error[E0507]: cannot move out of `rm.0` which is behind a mutable reference +error[E0507]: cannot move out of `rm` as enum variant `One` which is behind a mutable reference --> $DIR/simple.rs:215:38 | LL | while let &mut Either::One(_t) = rm { } @@ -332,7 +332,7 @@ LL | while let &mut Either::One(_t) = rm { } | | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | help: consider removing the `&mut`: `Either::One(_t)` -error[E0507]: cannot move out of `rm.0` which is behind a mutable reference +error[E0507]: cannot move out of `rm` as enum variant `Two` which is behind a mutable reference --> $DIR/simple.rs:219:11 | LL | match rm { @@ -354,7 +354,7 @@ help: consider removing the `&mut` LL | Either::Two(_t) => (), | ~~~~~~~~~~~~~~~ -error[E0507]: cannot move out of `rm.0` which is behind a mutable reference +error[E0507]: cannot move out of `rm` as enum variant `One` which is behind a mutable reference --> $DIR/simple.rs:228:11 | LL | match rm { @@ -367,7 +367,7 @@ LL | &mut Either::One(_t) => (), | | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | help: consider removing the `&mut`: `Either::One(_t)` -error[E0507]: cannot move out of `rm.0` which is behind a mutable reference +error[E0507]: cannot move out of `rm` as enum variant `One` which is behind a mutable reference --> $DIR/simple.rs:235:11 | LL | match rm { @@ -380,7 +380,7 @@ LL | &mut Either::One(_t) => (), | | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | help: consider removing the `&mut`: `Either::One(_t)` -error[E0507]: cannot move out of `rm.0` which is behind a mutable reference +error[E0507]: cannot move out of `rm` as enum variant `One` which is behind a mutable reference --> $DIR/simple.rs:242:11 | LL | match rm {