Skip to content

Commit 7b08827

Browse files
author
Jakub Wieczorek
committed
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.
1 parent 5d335c9 commit 7b08827

File tree

6 files changed

+50
-7
lines changed

6 files changed

+50
-7
lines changed

src/librustc/middle/borrowck/check_loans.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,8 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
494494
euv::AutoRef(..) |
495495
euv::ClosureInvocation(..) |
496496
euv::ForLoop(..) |
497-
euv::RefBinding(..) => {
497+
euv::RefBinding(..) |
498+
euv::MatchDiscriminant(..) => {
498499
format!("previous borrow of `{}` occurs here",
499500
self.bccx.loan_path_to_string(&*old_loan.loan_path))
500501
}

src/librustc/middle/borrowck/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
648648
euv::AddrOf |
649649
euv::RefBinding |
650650
euv::AutoRef |
651-
euv::ForLoop => {
651+
euv::ForLoop |
652+
euv::MatchDiscriminant => {
652653
format!("cannot borrow {} as mutable", descr)
653654
}
654655
euv::ClosureInvocation => {
@@ -702,7 +703,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
702703
BorrowViolation(euv::OverloadedOperator) |
703704
BorrowViolation(euv::AddrOf) |
704705
BorrowViolation(euv::AutoRef) |
705-
BorrowViolation(euv::RefBinding) => {
706+
BorrowViolation(euv::RefBinding) |
707+
BorrowViolation(euv::MatchDiscriminant) => {
706708
"cannot borrow data mutably"
707709
}
708710

src/librustc/middle/expr_use_visitor.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ pub enum LoanCause {
8282
OverloadedOperator,
8383
ClosureInvocation,
8484
ForLoop,
85+
MatchDiscriminant
8586
}
8687

8788
#[deriving(PartialEq,Show)]
@@ -374,10 +375,10 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
374375
}
375376

376377
ast::ExprMatch(ref discr, ref arms) => {
377-
// treatment of the discriminant is handled while
378-
// walking the arms:
379-
self.walk_expr(&**discr);
380378
let discr_cmt = return_if_err!(self.mc.cat_expr(&**discr));
379+
self.borrow_expr(&**discr, ty::ReEmpty, ty::ImmBorrow, MatchDiscriminant);
380+
381+
// treatment of the discriminant is handled while walking the arms.
381382
for arm in arms.iter() {
382383
self.walk_arm(discr_cmt.clone(), arm);
383384
}

src/librustc/middle/ty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3308,7 +3308,7 @@ pub fn ty_region(tcx: &ctxt,
33083308
ref s => {
33093309
tcx.sess.span_bug(
33103310
span,
3311-
format!("ty_region() invoked on in appropriate ty: {:?}",
3311+
format!("ty_region() invoked on an inappropriate ty: {:?}",
33123312
s).as_slice());
33133313
}
33143314
}

src/test/compile-fail/issue-17385.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
struct X(int);
12+
13+
enum Enum {
14+
Variant1,
15+
Variant2
16+
}
17+
18+
impl Drop for X {
19+
fn drop(&mut self) {}
20+
}
21+
impl Drop for Enum {
22+
fn drop(&mut self) {}
23+
}
24+
25+
fn main() {
26+
let foo = X(1i);
27+
drop(foo);
28+
match foo { //~ ERROR use of moved value
29+
X(1i) => (),
30+
_ => unreachable!()
31+
}
32+
33+
let e = Variant2;
34+
drop(e);
35+
match e { //~ ERROR use of moved value
36+
Variant1 => unreachable!(),
37+
Variant2 => ()
38+
}
39+
}

0 commit comments

Comments
 (0)