Skip to content

Commit 21dd404

Browse files
committed
Track what drop obligations are established on match arms.
This is accomplished by: 1. Add `MatchMode` enum to `expr_use_visitor`. 2. Computing the match mode for each pattern via a pre-pass, and then passing the mode along when visiting the pattern in expr_use_visitor. 3. Adding a `fn matched_pat` callback to expr_use_visitor, which is called on all nodes of the pattern (as opposed to `fn consume_pat`, which is only invoked for identifiers at the leaves of the pattern), and invoking it accordingly. Of particular interest are the `cat_downcast` instances established when matching enum variants.
1 parent d84035b commit 21dd404

File tree

8 files changed

+295
-10
lines changed

8 files changed

+295
-10
lines changed

src/librustc/middle/borrowck/check_loans.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ impl<'a, 'tcx> euv::Delegate for CheckLoanCtxt<'a, 'tcx> {
100100
self.consume_common(consume_id, consume_span, cmt, mode);
101101
}
102102

103+
fn matched_pat(&mut self,
104+
_matched_pat: &ast::Pat,
105+
_cmt: mc::cmt,
106+
_mode: euv::MatchMode) { }
107+
103108
fn consume_pat(&mut self,
104109
consume_pat: &ast::Pat,
105110
cmt: mc::cmt,

src/librustc/middle/borrowck/gather_loans/gather_moves.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,35 @@ pub fn gather_move_from_expr(bccx: &BorrowckCtxt,
6161
gather_move(bccx, move_data, move_error_collector, move_info);
6262
}
6363

64+
pub fn gather_match_variant(bccx: &BorrowckCtxt,
65+
move_data: &MoveData,
66+
_move_error_collector: &MoveErrorCollector,
67+
move_pat: &ast::Pat,
68+
cmt: mc::cmt,
69+
mode: euv::MatchMode) {
70+
debug!("gather_match_variant(move_pat={}, cmt={}, mode={})",
71+
move_pat.id, cmt.repr(bccx.tcx), mode);
72+
73+
let opt_lp = opt_loan_path(&cmt);
74+
let opt_base_lp = match cmt.cat {
75+
mc::cat_downcast(ref base_cmt, _variant_def_id) => opt_loan_path(base_cmt),
76+
_ => fail!("should only encounter move_into_variant on cat_downcast."),
77+
};
78+
match (opt_lp, opt_base_lp) {
79+
(Some(loan_path), Some(base_loan_path)) => {
80+
move_data.add_variant_match(bccx.tcx,
81+
loan_path,
82+
move_pat.id,
83+
base_loan_path,
84+
mode);
85+
}
86+
(lp, base_lp) => {
87+
debug!("add_variant_match body for ({:?}, {:?}) NOT YET IMPLEMENTED", lp, base_lp);
88+
}
89+
}
90+
91+
}
92+
6493
pub fn gather_move_from_pat(bccx: &BorrowckCtxt,
6594
move_data: &MoveData,
6695
move_error_collector: &MoveErrorCollector,

src/librustc/middle/borrowck/gather_loans/mod.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,24 @@ impl<'a, 'tcx> euv::Delegate for GatherLoanCtxt<'a, 'tcx> {
8484
}
8585
}
8686

87+
fn matched_pat(&mut self,
88+
matched_pat: &ast::Pat,
89+
cmt: mc::cmt,
90+
mode: euv::MatchMode) {
91+
debug!("matched_pat(matched_pat={}, cmt={}, mode={})",
92+
matched_pat.repr(self.tcx()),
93+
cmt.repr(self.tcx()),
94+
mode);
95+
96+
match cmt.cat {
97+
mc::cat_downcast(..) =>
98+
gather_moves::gather_match_variant(
99+
self.bccx, &self.move_data, &self.move_error_collector,
100+
matched_pat, cmt, mode),
101+
_ => {}
102+
}
103+
}
104+
87105
fn consume_pat(&mut self,
88106
consume_pat: &ast::Pat,
89107
cmt: mc::cmt,

src/librustc/middle/borrowck/move_data.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,35 @@ impl MoveData {
495495
}
496496
}
497497

498+
pub fn add_variant_match(&self,
499+
tcx: &ty::ctxt,
500+
lp: Rc<LoanPath>,
501+
pattern_id: ast::NodeId,
502+
base_lp: Rc<LoanPath>,
503+
mode: euv::MatchMode) {
504+
/*!
505+
* Adds a new record for a match of `base_lp`, downcast to
506+
* variant `lp`, that occurs at location `pattern_id`. (One
507+
* should be able to recover the span info from the
508+
* `pattern_id` and the ast_map, I think.)
509+
*/
510+
debug!("add_variant_match(lp={}, pattern_id={:?})",
511+
lp.repr(tcx), pattern_id);
512+
513+
let path_index = self.move_path(tcx, lp.clone());
514+
let base_path_index = self.move_path(tcx, base_lp.clone());
515+
516+
self.nonfragments.borrow_mut().push(path_index);
517+
let variant_match = VariantMatch {
518+
path: path_index,
519+
base_path: base_path_index,
520+
id: pattern_id,
521+
mode: mode,
522+
};
523+
524+
self.variant_matches.borrow_mut().push(variant_match);
525+
}
526+
498527
fn add_gen_kills(&self,
499528
tcx: &ty::ctxt,
500529
dfcx_moves: &mut MoveDataFlow,

src/librustc/middle/check_match.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use middle::def::*;
1414
use middle::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, Init};
1515
use middle::expr_use_visitor::{JustWrite, LoanCause, MutateMode};
1616
use middle::expr_use_visitor::{WriteAndRead};
17+
use middle::expr_use_visitor as euv;
1718
use middle::mem_categorization::cmt;
1819
use middle::pat_util::*;
1920
use middle::ty::*;
@@ -982,6 +983,7 @@ struct MutationChecker<'a, 'tcx: 'a> {
982983
}
983984

984985
impl<'a, 'tcx> Delegate for MutationChecker<'a, 'tcx> {
986+
fn matched_pat(&mut self, _: &Pat, _: cmt, _: euv::MatchMode) {}
985987
fn consume(&mut self, _: NodeId, _: Span, _: cmt, _: ConsumeMode) {}
986988
fn consume_pat(&mut self, _: &Pat, _: cmt, _: ConsumeMode) {}
987989
fn borrow(&mut self,

src/librustc/middle/check_rvalues.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ impl<'a, 'tcx> euv::Delegate for RvalueContext<'a, 'tcx> {
5656
}
5757
}
5858

59+
fn matched_pat(&mut self,
60+
_matched_pat: &ast::Pat,
61+
_cmt: mc::cmt,
62+
_mode: euv::MatchMode) {}
63+
5964
fn consume_pat(&mut self,
6065
_consume_pat: &ast::Pat,
6166
_cmt: mc::cmt,

0 commit comments

Comments
 (0)