Skip to content

Commit a7f5d8a

Browse files
authored
Auto merge of #34672 - luqmana:27021-reassign-match-body, r=eddyb
Make match discriminant reassignment check more accurate. Fixes #27021.
2 parents b4e11c2 + a9c7a41 commit a7f5d8a

File tree

2 files changed

+38
-10
lines changed

2 files changed

+38
-10
lines changed

src/librustc_trans/_match.rs

+17-10
Original file line numberDiff line numberDiff line change
@@ -1495,20 +1495,27 @@ impl<'tcx> euv::Delegate<'tcx> for ReassignmentChecker {
14951495
fn decl_without_init(&mut self, _: ast::NodeId, _: Span) {}
14961496

14971497
fn mutate(&mut self, _: ast::NodeId, _: Span, cmt: mc::cmt, _: euv::MutateMode) {
1498+
let cmt_id = |cmt: &mc::cmt| match cmt.cat {
1499+
Categorization::Upvar(mc::Upvar { id: ty::UpvarId { var_id: vid, ..}, ..}) |
1500+
Categorization::Local(vid) => Some(vid),
1501+
Categorization::Interior(ref base_cmt, mc::InteriorField(_)) => Some(base_cmt.id),
1502+
_ => None
1503+
};
14981504
match cmt.cat {
14991505
Categorization::Upvar(mc::Upvar { id: ty::UpvarId { var_id: vid, .. }, .. }) |
15001506
Categorization::Local(vid) => self.reassigned |= self.node == vid,
1501-
Categorization::Interior(ref base_cmt, mc::InteriorField(field)) => {
1502-
match base_cmt.cat {
1503-
Categorization::Upvar(mc::Upvar { id: ty::UpvarId { var_id: vid, .. }, .. }) |
1504-
Categorization::Local(vid) => {
1505-
self.reassigned |= self.node == vid &&
1506-
(self.field.is_none() || Some(field) == self.field)
1507-
},
1508-
_ => {}
1507+
ref cat => {
1508+
let mut cat = cat;
1509+
while let &Categorization::Interior(ref base_cmt, mc::InteriorField(field)) = cat {
1510+
if let Some(vid) = cmt_id(base_cmt) {
1511+
if self.node == vid && (self.field.is_none() || self.field == Some(field)) {
1512+
self.reassigned = true;
1513+
return;
1514+
}
1515+
}
1516+
cat = &base_cmt.cat;
15091517
}
1510-
},
1511-
_ => {}
1518+
}
15121519
}
15131520
}
15141521
}

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

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2016 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+
fn main() {
12+
let mut c = (1, (1, "".to_owned()));
13+
match c {
14+
c2 => { (c.1).0 = 2; assert_eq!((c2.1).0, 1); }
15+
}
16+
17+
let mut c = (1, (1, (1, "".to_owned())));
18+
match c.1 {
19+
c2 => { ((c.1).1).0 = 3; assert_eq!((c2.1).0, 1); }
20+
}
21+
}

0 commit comments

Comments
 (0)