+/// Checks whether the binding in `discr` is assigned to anywhere in the expression `body`
+fn is_discr_reassigned(bcx: &Block, discr: &ast::Expr, body: &ast::Expr) -> bool {
+ match discr.node {
+ ast::ExprPath(..) => match bcx.def(discr.id) {
+ def::DefLocal(vid, _) | def::DefBinding(vid, _) => {
+ let mut rc = ReassignmentChecker {
+ node: vid,
+ reassigned: false
+ };
+ {
+ let mut visitor = euv::ExprUseVisitor::new(&mut rc, bcx);
+ visitor.walk_expr(body);
+ }
+ rc.reassigned
+ }
+ _ => false
+ },
+ _ => false
+ }
+}
+
+struct ReassignmentChecker {
+ node: ast::NodeId,
+ reassigned: bool
+}
+
+impl euv::Delegate for ReassignmentChecker {
+ fn consume(&mut self, _: ast::NodeId, _: Span, _: mc::cmt, _: euv::ConsumeMode) {}
+ fn consume_pat(&mut self, _: &ast::Pat, _: mc::cmt, _: euv::ConsumeMode) {}
+ fn borrow(&mut self, _: ast::NodeId, _: Span, _: mc::cmt, _: ty::Region,
+ _: ty::BorrowKind, _: euv::LoanCause) {}
+ fn decl_without_init(&mut self, _: ast::NodeId, _: Span) {}
+ fn mutate(&mut self, _: ast::NodeId, _: Span, cmt: mc::cmt, _: euv::MutateMode) {
+ match cmt.cat {
+ mc::cat_local(vid) => self.reassigned = self.node == vid,
+ _ => {}
+ }
+ }
+}
+
+fn create_bindings_map(bcx: &Block, pat: Gc<ast::Pat>,
+ discr: &ast::Expr, body: &ast::Expr) -> BindingsMap {