mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 23:34:48 +00:00
Induce an empty loan for the value being matched in match expressions
This is to make sure it hadn't been moved if there are no bindings in any of the arms. Fixes #17385.
This commit is contained in:
parent
5d335c94bd
commit
7b08827f2d
@ -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))
|
||||
}
|
||||
|
@ -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"
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
39
src/test/compile-fail/issue-17385.rs
Normal file
39
src/test/compile-fail/issue-17385.rs
Normal file
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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 => ()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user