diff options
| author | Matthew Jasper <mjjasper1@gmail.com> | 2019-06-29 15:38:20 +0100 |
|---|---|---|
| committer | Matthew Jasper <mjjasper1@gmail.com> | 2019-07-06 21:56:03 +0100 |
| commit | de5c6ec1f4a6bbd8600fda0e7c1574d914ac35bd (patch) | |
| tree | 7f35c15a9f202554d9491e1b6a38782b7993dca8 /src | |
| parent | db6f77f0d74934a95eb91d74bda19e5b0e8258e3 (diff) | |
| download | rust-de5c6ec1f4a6bbd8600fda0e7c1574d914ac35bd.tar.gz rust-de5c6ec1f4a6bbd8600fda0e7c1574d914ac35bd.zip | |
Exit arm scopes correctly in the HIR CFG
When a match evaluates to false we jump to the next arm, when we do so we need to make sure that we exit the scope for that arm.
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc/cfg/construct.rs | 13 | ||||
| -rw-r--r-- | src/test/ui/borrowck/issue-62107-match-arm-scopes.rs | 12 | ||||
| -rw-r--r-- | src/test/ui/borrowck/issue-62107-match-arm-scopes.stderr | 9 |
3 files changed, 28 insertions, 6 deletions
diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index f81d1869413..ca852fe7622 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -371,7 +371,8 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { let expr_exit = self.add_ast_node(id, &[]); // Keep track of the previous guard expressions - let mut prev_guards = Vec::new(); + let mut prev_guard = None; + let match_scope = region::Scope { id, data: region::ScopeData::Node }; for arm in arms { // Add an exit node for when we've visited all the @@ -389,7 +390,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { let guard_start = self.add_dummy_node(&[pat_exit]); // Visit the guard expression let guard_exit = match guard { - hir::Guard::If(ref e) => self.expr(e, guard_start), + hir::Guard::If(ref e) => (&**e, self.expr(e, guard_start)), }; // #47295: We used to have very special case code // here for when a pair of arms are both formed @@ -397,15 +398,15 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { // edges. But this was not actually sound without // other constraints that we stopped enforcing at // some point. - while let Some(prev) = prev_guards.pop() { - self.add_contained_edge(prev, guard_start); + if let Some((prev_guard, prev_index)) = prev_guard.take() { + self.add_exiting_edge(prev_guard, prev_index, match_scope, guard_start); } // Push the guard onto the list of previous guards - prev_guards.push(guard_exit); + prev_guard = Some(guard_exit); // Update the exit node for the pattern - pat_exit = guard_exit; + pat_exit = guard_exit.1; } // Add an edge from the exit of this pattern to the diff --git a/src/test/ui/borrowck/issue-62107-match-arm-scopes.rs b/src/test/ui/borrowck/issue-62107-match-arm-scopes.rs new file mode 100644 index 00000000000..220b2ecf04d --- /dev/null +++ b/src/test/ui/borrowck/issue-62107-match-arm-scopes.rs @@ -0,0 +1,12 @@ +fn main() { + let e: i32; + match e { + //~^ ERROR use of possibly uninitialized variable + ref u if true => {} + ref v if true => { + let tx = 0; + &tx; + } + _ => (), + } +} diff --git a/src/test/ui/borrowck/issue-62107-match-arm-scopes.stderr b/src/test/ui/borrowck/issue-62107-match-arm-scopes.stderr new file mode 100644 index 00000000000..9701343d2b1 --- /dev/null +++ b/src/test/ui/borrowck/issue-62107-match-arm-scopes.stderr @@ -0,0 +1,9 @@ +error[E0381]: use of possibly uninitialized variable: `e` + --> $DIR/issue-62107-match-arm-scopes.rs:3:11 + | +LL | match e { + | ^ use of possibly uninitialized `e` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0381`. |
