diff options
| author | Björn Steinbrink <bsteinbr@gmail.com> | 2015-03-25 14:50:04 +0100 |
|---|---|---|
| committer | Björn Steinbrink <bsteinbr@gmail.com> | 2015-03-25 14:50:04 +0100 |
| commit | cc259fb6c36c6033d2befcb11535a98adda03b3f (patch) | |
| tree | d84d4303a5ba6db44f9d28272dac205a6c955a78 | |
| parent | 28a0b25f424090255966273994748a9f9901059f (diff) | |
| download | rust-cc259fb6c36c6033d2befcb11535a98adda03b3f.tar.gz rust-cc259fb6c36c6033d2befcb11535a98adda03b3f.zip | |
Always properly copy values into bindings when mutating the match discriminant
The reassignment checker effectively only checks whether the last assignment in a body affects the discriminant, but it should of course check all the assignments. Fixes #23698
| -rw-r--r-- | src/librustc_trans/trans/_match.rs | 4 | ||||
| -rw-r--r-- | src/test/run-pass/match-reassign.rs | 30 |
2 files changed, 32 insertions, 2 deletions
diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index c08d3b2be53..05d215e17c5 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -1352,12 +1352,12 @@ impl<'tcx> euv::Delegate<'tcx> for ReassignmentChecker { fn mutate(&mut self, _: ast::NodeId, _: Span, cmt: mc::cmt, _: euv::MutateMode) { match cmt.cat { mc::cat_upvar(mc::Upvar { id: ty::UpvarId { var_id: vid, .. }, .. }) | - mc::cat_local(vid) => self.reassigned = self.node == vid, + mc::cat_local(vid) => self.reassigned |= self.node == vid, mc::cat_interior(ref base_cmt, mc::InteriorField(field)) => { match base_cmt.cat { mc::cat_upvar(mc::Upvar { id: ty::UpvarId { var_id: vid, .. }, .. }) | mc::cat_local(vid) => { - self.reassigned = self.node == vid && Some(field) == self.field + self.reassigned |= self.node == vid && Some(field) == self.field }, _ => {} } diff --git a/src/test/run-pass/match-reassign.rs b/src/test/run-pass/match-reassign.rs new file mode 100644 index 00000000000..759296ad46b --- /dev/null +++ b/src/test/run-pass/match-reassign.rs @@ -0,0 +1,30 @@ +// Copyright 2015 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. + +// Regression test for #23698: The reassignment checker only cared +// about the last assigment in a match arm body + +// Use an extra function to make sure no extra assignments +// are introduced by macros in the match statement +fn check_eq(x: i32, y: i32) { + assert_eq!(x, y); +} + +#[allow(unused_assignments)] +fn main() { + let mut x = Box::new(1); + match x { + y => { + x = Box::new(2); + let _tmp = 1; // This assignment used to throw off the reassignment checker + check_eq(*y, 1); + } + } +} |
