From db6f77f0d74934a95eb91d74bda19e5b0e8258e3 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sat, 29 Jun 2019 15:31:43 +0100 Subject: [PATCH 1/2] Add arm ids for -Zunpretty=hir,identified --- src/librustc/hir/print.rs | 3 +++ src/librustc_borrowck/dataflow.rs | 3 ++- src/librustc_driver/pretty.rs | 20 ++++++++++---------- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 367e4dba042cd..6817107635a60 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -27,6 +27,7 @@ pub enum AnnNode<'a> { SubItem(hir::HirId), Expr(&'a hir::Expr), Pat(&'a hir::Pat), + Arm(&'a hir::Arm), } pub enum Nested { @@ -1821,6 +1822,7 @@ impl<'a> State<'a> { self.s.space(); } self.cbox(indent_unit); + self.ann.pre(self, AnnNode::Arm(arm)); self.ibox(0); self.print_outer_attributes(&arm.attrs); let mut first = true; @@ -1865,6 +1867,7 @@ impl<'a> State<'a> { self.s.word(","); } } + self.ann.post(self, AnnNode::Arm(arm)); self.end() // close enclosing cbox } diff --git a/src/librustc_borrowck/dataflow.rs b/src/librustc_borrowck/dataflow.rs index 95580952ffb95..f1f9f3f71e4a3 100644 --- a/src/librustc_borrowck/dataflow.rs +++ b/src/librustc_borrowck/dataflow.rs @@ -109,7 +109,8 @@ impl<'tcx, O: DataFlowOperator> pprust::PpAnn for DataFlowContext<'tcx, O> { pprust::AnnNode::Block(blk) => blk.hir_id.local_id, pprust::AnnNode::Item(_) | pprust::AnnNode::SubItem(_) => return, - pprust::AnnNode::Pat(pat) => pat.hir_id.local_id + pprust::AnnNode::Pat(pat) => pat.hir_id.local_id, + pprust::AnnNode::Arm(arm) => arm.hir_id.local_id, }; if !self.has_bitset_for_local_id(id) { diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index f314af43f99a4..fc55d5ac3559a 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -387,28 +387,28 @@ impl<'hir> pprust_hir::PpAnn for IdentifiedAnnotation<'hir> { pprust_hir::AnnNode::Name(_) => {}, pprust_hir::AnnNode::Item(item) => { s.s.space(); - s.synth_comment(format!("hir_id: {} hir local_id: {}", - item.hir_id, item.hir_id.local_id.as_u32())) + s.synth_comment(format!("hir_id: {}", item.hir_id)); } pprust_hir::AnnNode::SubItem(id) => { s.s.space(); - s.synth_comment(id.to_string()) + s.synth_comment(id.to_string()); } pprust_hir::AnnNode::Block(blk) => { s.s.space(); - s.synth_comment(format!("block hir_id: {} hir local_id: {}", - blk.hir_id, blk.hir_id.local_id.as_u32())) + s.synth_comment(format!("block hir_id: {}", blk.hir_id)); } pprust_hir::AnnNode::Expr(expr) => { s.s.space(); - s.synth_comment(format!("expr hir_id: {} hir local_id: {}", - expr.hir_id, expr.hir_id.local_id.as_u32())); - s.pclose() + s.synth_comment(format!("expr hir_id: {}", expr.hir_id)); + s.pclose(); } pprust_hir::AnnNode::Pat(pat) => { s.s.space(); - s.synth_comment(format!("pat hir_id: {} hir local_id: {}", - pat.hir_id, pat.hir_id.local_id.as_u32())) + s.synth_comment(format!("pat hir_id: {}", pat.hir_id)); + } + pprust_hir::AnnNode::Arm(arm) => { + s.s.space(); + s.synth_comment(format!("arm hir_id: {}", arm.hir_id)); } } } From de5c6ec1f4a6bbd8600fda0e7c1574d914ac35bd Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sat, 29 Jun 2019 15:38:20 +0100 Subject: [PATCH 2/2] 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. --- src/librustc/cfg/construct.rs | 13 +++++++------ .../ui/borrowck/issue-62107-match-arm-scopes.rs | 12 ++++++++++++ .../ui/borrowck/issue-62107-match-arm-scopes.stderr | 9 +++++++++ 3 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/borrowck/issue-62107-match-arm-scopes.rs create mode 100644 src/test/ui/borrowck/issue-62107-match-arm-scopes.stderr diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index f81d18694136e..ca852fe7622cc 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 0000000000000..220b2ecf04d38 --- /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 0000000000000..9701343d2b1dd --- /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`.