Make match discriminant reassignment check more accurate.
This commit is contained in:
parent
ec58d0c997
commit
a9c7a41576
@ -1495,20 +1495,27 @@ impl<'tcx> euv::Delegate<'tcx> for ReassignmentChecker {
|
||||
fn decl_without_init(&mut self, _: ast::NodeId, _: Span) {}
|
||||
|
||||
fn mutate(&mut self, _: ast::NodeId, _: Span, cmt: mc::cmt, _: euv::MutateMode) {
|
||||
let cmt_id = |cmt: &mc::cmt| match cmt.cat {
|
||||
Categorization::Upvar(mc::Upvar { id: ty::UpvarId { var_id: vid, ..}, ..}) |
|
||||
Categorization::Local(vid) => Some(vid),
|
||||
Categorization::Interior(ref base_cmt, mc::InteriorField(_)) => Some(base_cmt.id),
|
||||
_ => None
|
||||
};
|
||||
match cmt.cat {
|
||||
Categorization::Upvar(mc::Upvar { id: ty::UpvarId { var_id: vid, .. }, .. }) |
|
||||
Categorization::Local(vid) => self.reassigned |= self.node == vid,
|
||||
Categorization::Interior(ref base_cmt, mc::InteriorField(field)) => {
|
||||
match base_cmt.cat {
|
||||
Categorization::Upvar(mc::Upvar { id: ty::UpvarId { var_id: vid, .. }, .. }) |
|
||||
Categorization::Local(vid) => {
|
||||
self.reassigned |= self.node == vid &&
|
||||
(self.field.is_none() || Some(field) == self.field)
|
||||
},
|
||||
_ => {}
|
||||
ref cat => {
|
||||
let mut cat = cat;
|
||||
while let &Categorization::Interior(ref base_cmt, mc::InteriorField(field)) = cat {
|
||||
if let Some(vid) = cmt_id(base_cmt) {
|
||||
if self.node == vid && (self.field.is_none() || self.field == Some(field)) {
|
||||
self.reassigned = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
cat = &base_cmt.cat;
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
21
src/test/run-pass/issue-27021.rs
Normal file
21
src/test/run-pass/issue-27021.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
fn main() {
|
||||
let mut c = (1, (1, "".to_owned()));
|
||||
match c {
|
||||
c2 => { (c.1).0 = 2; assert_eq!((c2.1).0, 1); }
|
||||
}
|
||||
|
||||
let mut c = (1, (1, (1, "".to_owned())));
|
||||
match c.1 {
|
||||
c2 => { ((c.1).1).0 = 3; assert_eq!((c2.1).0, 1); }
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user