diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index 95009bc2dbfc..e9be87758f95 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -494,7 +494,8 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { euv::AutoRef(..) | euv::ClosureInvocation(..) | euv::ForLoop(..) | - euv::RefBinding(..) => { + euv::RefBinding(..) | + euv::MatchDiscriminant(..) => { format!("previous borrow of `{}` occurs here", self.bccx.loan_path_to_string(&*old_loan.loan_path)) } diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index e1e37b3d371a..7d734323ee82 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -648,7 +648,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { euv::AddrOf | euv::RefBinding | euv::AutoRef | - euv::ForLoop => { + euv::ForLoop | + euv::MatchDiscriminant => { format!("cannot borrow {} as mutable", descr) } euv::ClosureInvocation => { @@ -702,7 +703,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { BorrowViolation(euv::OverloadedOperator) | BorrowViolation(euv::AddrOf) | BorrowViolation(euv::AutoRef) | - BorrowViolation(euv::RefBinding) => { + BorrowViolation(euv::RefBinding) | + BorrowViolation(euv::MatchDiscriminant) => { "cannot borrow data mutably" } diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 0b4f661a16ab..81994ee64a8c 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -82,6 +82,7 @@ pub enum LoanCause { OverloadedOperator, ClosureInvocation, ForLoop, + MatchDiscriminant } #[deriving(PartialEq,Show)] @@ -374,10 +375,10 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> { } ast::ExprMatch(ref discr, ref arms) => { - // treatment of the discriminant is handled while - // walking the arms: - self.walk_expr(&**discr); let discr_cmt = return_if_err!(self.mc.cat_expr(&**discr)); + self.borrow_expr(&**discr, ty::ReEmpty, ty::ImmBorrow, MatchDiscriminant); + + // treatment of the discriminant is handled while walking the arms. for arm in arms.iter() { self.walk_arm(discr_cmt.clone(), arm); } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 33ade80afd3c..469cdad076da 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3308,7 +3308,7 @@ pub fn ty_region(tcx: &ctxt, ref s => { tcx.sess.span_bug( span, - format!("ty_region() invoked on in appropriate ty: {:?}", + format!("ty_region() invoked on an inappropriate ty: {:?}", s).as_slice()); } } diff --git a/src/test/compile-fail/issue13359.rs b/src/test/compile-fail/issue-13359.rs similarity index 100% rename from src/test/compile-fail/issue13359.rs rename to src/test/compile-fail/issue-13359.rs diff --git a/src/test/compile-fail/issue-17385.rs b/src/test/compile-fail/issue-17385.rs new file mode 100644 index 000000000000..bc1495ac4543 --- /dev/null +++ b/src/test/compile-fail/issue-17385.rs @@ -0,0 +1,39 @@ +// Copyright 2014 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. + +struct X(int); + +enum Enum { + Variant1, + Variant2 +} + +impl Drop for X { + fn drop(&mut self) {} +} +impl Drop for Enum { + fn drop(&mut self) {} +} + +fn main() { + let foo = X(1i); + drop(foo); + match foo { //~ ERROR use of moved value + X(1i) => (), + _ => unreachable!() + } + + let e = Variant2; + drop(e); + match e { //~ ERROR use of moved value + Variant1 => unreachable!(), + Variant2 => () + } +}