From 3dfe256b5f85a05f29a55e07d8327f5d95e12719 Mon Sep 17 00:00:00 2001 From: David Wood Date: Fri, 22 Dec 2017 15:00:26 +0000 Subject: [PATCH] Added 'move occurs because `X` is not `Copy`' note. --- .../borrow_check/error_reporting.rs | 46 ++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index c144962fb2d..87b8a6ae584 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -81,7 +81,34 @@ pub(super) fn report_use_of_moved_or_uninitialized( err.span_label(move_span, format!("value moved{} here", move_msg)); }; } - //FIXME: add note for closure + + if let Some(ty) = self.retrieve_type_for_place(place) { + let needs_note = match ty.sty { + ty::TypeVariants::TyClosure(id, _) => { + let tables = self.tcx.typeck_tables_of(id); + let node_id = self.tcx.hir.as_local_node_id(id).unwrap(); + let hir_id = self.tcx.hir.node_to_hir_id(node_id); + if let Some(_) = tables.closure_kind_origins().get(hir_id) { + false + } else { + true + } + }, + _ => true, + }; + + if needs_note { + let note_msg = match self.describe_place(place) { + Some(name) => format!("`{}`", name), + None => "value".to_owned(), + }; + + err.note(&format!("move occurs because {} has type `{}`, \ + which does not implement the `Copy` trait", + note_msg, ty)); + } + } + err.emit(); } } @@ -655,4 +682,21 @@ fn describe_field_from_ty(&self, ty: &ty::Ty, field: Field) -> String { fn retrieve_borrow_span(&self, borrow: &BorrowData) -> Span { self.mir.source_info(borrow.location).span } + + // Retrieve type of a place for the current MIR representation + fn retrieve_type_for_place(&self, place: &Place<'tcx>) -> Option { + match place { + Place::Local(local) => { + let local = &self.mir.local_decls[*local]; + Some(local.ty) + }, + Place::Static(ref st) => Some(st.ty), + Place::Projection(ref proj) => { + match proj.elem { + ProjectionElem::Field(_, ty) => Some(ty), + _ => None, + } + }, + } + } }