diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index f755efc89a58e..4dd9ee4ab33bd 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -46,7 +46,7 @@ use std::fmt; use std::rc::Rc; use std::hash::{Hash, Hasher}; use syntax::ast; -use syntax_pos::{MultiSpan, Span}; +use syntax_pos::{MultiSpan, Span, SyntaxContext}; use errors::{DiagnosticBuilder, DiagnosticId}; use rustc::hir; @@ -723,18 +723,17 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { // Annotate the use and the move in the span. Watch out for // the case where the use and the move are the same. This - // means the use is in a loop. - err = if use_span == move_span { - err.span_label( - use_span, - format!("value moved{} here in previous iteration of loop", - move_note)); - err + // means the use is in a loop or within the same macro invocation. + if use_span == move_span && use_span.ctxt() != SyntaxContext::empty() { + err.span_label(use_span, format!("value moved{} here in previous iteration of loop", + move_note)); + } else if use_span == move_span { + err.span_label(use_span, format!("value moved{} inside this macro invocation", + move_note)); } else { err.span_label(use_span, format!("value {} here after move", verb_participle)); err.span_label(move_span, format!("value moved{} here", move_note)); - err - }; + } if need_note { err.note(&format!( diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 7bd3b6e39f053..008c8dcc82517 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use syntax_pos::Span; +use syntax_pos::{Span, SyntaxContext}; use rustc::middle::region::ScopeTree; use rustc::mir::{BorrowKind, Field, Local, LocalKind, Location, Operand}; use rustc::mir::{Place, ProjectionElem, Rvalue, Statement, StatementKind}; @@ -66,11 +66,14 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { for moi in mois { let move_msg = ""; //FIXME: add " (into closure)" let move_span = self.mir.source_info(self.move_data.moves[*moi].source).span; - if span == move_span { - err.span_label( - span, - format!("value moved{} here in previous iteration of loop", move_msg), - ); + if span == move_span && span.ctxt() != SyntaxContext::empty() { + err.span_label(span, format!("value moved{} inside this macro invocation", + move_msg)); + is_loop_move = true; + } else if span == move_span { + err.span_label(span, + format!("value moved{} here in previous iteration of loop", + move_msg)); is_loop_move = true; } else { err.span_label(move_span, format!("value moved{} here", move_msg)); diff --git a/src/test/ui/borrowck/moves-inside-of-macro.rs b/src/test/ui/borrowck/moves-inside-of-macro.rs new file mode 100644 index 0000000000000..3f589298fb530 --- /dev/null +++ b/src/test/ui/borrowck/moves-inside-of-macro.rs @@ -0,0 +1,25 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Z borrowck=compare + +macro_rules! test { + ($v:expr) => {{ + drop(&$v); + $v + }} +} + +fn main() { + let b = Box::new(true); + test!({b}); + //~^ ERROR use of moved value: `b` (Ast) + //~^^ ERROR use of moved value: `b` (Mir) +} diff --git a/src/test/ui/borrowck/moves-inside-of-macro.stderr b/src/test/ui/borrowck/moves-inside-of-macro.stderr new file mode 100644 index 0000000000000..2086bc0e50ac1 --- /dev/null +++ b/src/test/ui/borrowck/moves-inside-of-macro.stderr @@ -0,0 +1,10 @@ +error[E0382]: use of moved value: `b` + --> $DIR/moves-inside-of-macro.rs:20:12 + | +20 | test!({b}); + | ^ value moved inside this macro invocation + | + = note: move occurs because `b` has type `std::boxed::Box`, which does not implement the `Copy` trait + +error: aborting due to previous error +