Skip to content

Commit 5dca9fb

Browse files
committed
librustc: Also use new alloca if matching on an arg or upvar which we reassign in the arm body.
1 parent d7c0f7d commit 5dca9fb

File tree

2 files changed

+51
-4
lines changed

2 files changed

+51
-4
lines changed

src/librustc/middle/trans/_match.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1298,7 +1298,8 @@ pub fn trans_match<'a>(
12981298
fn is_discr_reassigned(bcx: &Block, discr: &ast::Expr, body: &ast::Expr) -> bool {
12991299
match discr.node {
13001300
ast::ExprPath(..) => match bcx.def(discr.id) {
1301-
def::DefLocal(vid, _) | def::DefBinding(vid, _) => {
1301+
def::DefArg(vid, _) | def::DefBinding(vid, _) |
1302+
def::DefLocal(vid, _) | def::DefUpvar(vid, _, _, _) => {
13021303
let mut rc = ReassignmentChecker {
13031304
node: vid,
13041305
reassigned: false
@@ -1326,9 +1327,11 @@ impl euv::Delegate for ReassignmentChecker {
13261327
fn borrow(&mut self, _: ast::NodeId, _: Span, _: mc::cmt, _: ty::Region,
13271328
_: ty::BorrowKind, _: euv::LoanCause) {}
13281329
fn decl_without_init(&mut self, _: ast::NodeId, _: Span) {}
1330+
13291331
fn mutate(&mut self, _: ast::NodeId, _: Span, cmt: mc::cmt, _: euv::MutateMode) {
13301332
match cmt.cat {
1331-
mc::cat_local(vid) => self.reassigned = self.node == vid,
1333+
mc::cat_copied_upvar(mc::CopiedUpvar { upvar_id: vid, .. }) |
1334+
mc::cat_arg(vid) | mc::cat_local(vid) => self.reassigned = self.node == vid,
13321335
_ => {}
13331336
}
13341337
}

src/test/run-pass/issue-15571.rs

+46-2
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,57 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
fn main() {
11+
fn match_on_local() {
1212
let mut foo = Some(box 5i);
1313
match foo {
1414
None => {},
1515
Some(x) => {
1616
foo = Some(x);
1717
}
18-
};
18+
}
1919
println!("'{}'", foo.unwrap());
2020
}
21+
22+
fn match_on_arg(mut foo: Option<Box<int>>) {
23+
match foo {
24+
None => {}
25+
Some(x) => {
26+
foo = Some(x);
27+
}
28+
}
29+
println!("'{}'", foo.unwrap());
30+
}
31+
32+
fn match_on_binding() {
33+
match Some(box 7i) {
34+
mut foo => {
35+
match foo {
36+
None => {},
37+
Some(x) => {
38+
foo = Some(x);
39+
}
40+
}
41+
println!("'{}'", foo.unwrap());
42+
}
43+
}
44+
}
45+
46+
fn match_on_upvar() {
47+
let mut foo = Some(box 8i);
48+
(proc() {
49+
match foo {
50+
None => {},
51+
Some(x) => {
52+
foo = Some(x);
53+
}
54+
}
55+
println!("'{}'", foo.unwrap());
56+
})();
57+
}
58+
59+
fn main() {
60+
match_on_local();
61+
match_on_arg(Some(box 6i));
62+
match_on_binding();
63+
match_on_upvar();
64+
}

0 commit comments

Comments
 (0)