Skip to content

Commit f7abf47

Browse files
committed
Re-introduce McResult<> as a way of aborting mem-categorization (and
expr-use-visitor) early. Turns out I was wrong to remove this; it causes a lot of pain trying to run EUV etc during typeck without ICEing on erroneous programs.
1 parent fc2ba13 commit f7abf47

File tree

5 files changed

+175
-130
lines changed

5 files changed

+175
-130
lines changed

src/librustc/middle/expr_use_visitor.rs

Lines changed: 46 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,20 @@ pub struct ExprUseVisitor<'d,'t,'tcx:'t,TYPER:'t> {
300300
mc: mc::MemCategorizationContext<'t,TYPER>,
301301
delegate: &'d mut (Delegate<'tcx>+'d),
302302
param_env: &'t ParameterEnvironment<'tcx>,
303+
// If the TYPER results in an error, it's because the type check
304+
// failed (or will fail, when the error is uncovered and reported
305+
// during writeback). In this case, we just ignore this part of the
306+
// code.
307+
//
308+
// Note that this macro appears similar to try!(), but, unlike try!(),
309+
// it does not propagate the error.
310+
macro_rules! return_if_err {
311+
($inp: expr) => (
312+
match $inp {
313+
Ok(v) => v,
314+
Err(()) => return
315+
}
316+
)
303317
}
304318

305319
/// Whether the elements of an overloaded operation are passed by value or by reference
@@ -332,7 +346,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
332346
decl: &ast::FnDecl,
333347
body: &ast::Block) {
334348
for arg in decl.inputs.iter() {
335-
let arg_ty = self.typer.node_ty(arg.pat.id);
349+
let arg_ty = return_if_err!(self.typer.node_ty(arg.pat.id));
336350

337351
let fn_body_scope = region::CodeExtent::from_node_id(body.id);
338352
let arg_cmt = self.mc.cat_rvalue(
@@ -369,7 +383,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
369383
pub fn consume_expr(&mut self, expr: &ast::Expr) {
370384
debug!("consume_expr(expr={})", expr.repr(self.tcx()));
371385

372-
let cmt = self.mc.cat_expr(expr);
386+
let cmt = return_if_err!(self.mc.cat_expr(expr));
373387
self.delegate_consume(expr.id, expr.span, cmt);
374388
self.walk_expr(expr);
375389
}
@@ -378,7 +392,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
378392
assignment_expr: &ast::Expr,
379393
expr: &ast::Expr,
380394
mode: MutateMode) {
381-
let cmt = self.mc.cat_expr(expr);
395+
let cmt = return_if_err!(self.mc.cat_expr(expr));
382396
self.delegate.mutate(assignment_expr.id, assignment_expr.span, cmt, mode);
383397
self.walk_expr(expr);
384398
}
@@ -391,7 +405,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
391405
debug!("borrow_expr(expr={}, r={}, bk={})",
392406
expr.repr(self.tcx()), r.repr(self.tcx()), bk.repr(self.tcx()));
393407

394-
let cmt = self.mc.cat_expr(expr);
408+
let cmt = return_if_err!(self.mc.cat_expr(expr));
395409
self.delegate.borrow(expr.id, expr.span, cmt, r, bk, cause);
396410

397411
// Note: Unlike consume, we can ignore ExprParen. cat_expr
@@ -491,7 +505,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
491505
}
492506

493507
ast::ExprMatch(ref discr, ref arms, _) => {
494-
let discr_cmt = self.mc.cat_expr(&**discr);
508+
let discr_cmt = return_if_err!(self.mc.cat_expr(&**discr));
495509
self.borrow_expr(&**discr, ty::ReEmpty, ty::ImmBorrow, MatchDiscriminant);
496510

497511
// treatment of the discriminant is handled while walking the arms.
@@ -509,7 +523,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
509523
ast::ExprAddrOf(m, ref base) => { // &base
510524
// make sure that the thing we are pointing out stays valid
511525
// for the lifetime `scope_r` of the resulting ptr:
512-
let expr_ty = ty::expr_ty(self.tcx(), expr);
526+
let expr_ty = return_if_err!(self.typer.node_ty(expr.id));
513527
let r = ty::ty_region(self.tcx(), expr.span, expr_ty);
514528
let bk = ty::BorrowKind::from_mutbl(m);
515529
self.borrow_expr(&**base, r, bk, AddrOf);
@@ -550,7 +564,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
550564

551565
// Fetch the type of the value that the iteration yields to
552566
// produce the pattern's categorized mutable type.
553-
let pattern_type = self.typer.node_ty(pat.id);
567+
let pattern_type = return_if_err!(self.typer.node_ty(pat.id));
554568
let blk_scope = region::CodeExtent::from_node_id(blk.id);
555569
let pat_cmt = self.mc.cat_rvalue(pat.id,
556570
pat.span,
@@ -638,7 +652,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
638652
}
639653

640654
fn walk_callee(&mut self, call: &ast::Expr, callee: &ast::Expr) {
641-
let callee_ty = self.typer.expr_ty_adjusted(callee);
655+
let callee_ty = return_if_err!(self.typer.expr_ty_adjusted(callee));
642656
debug!("walk_callee: callee={} callee_ty={}",
643657
callee.repr(self.tcx()), callee_ty.repr(self.tcx()));
644658
let call_scope = region::CodeExtent::from_node_id(call.id);
@@ -735,7 +749,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
735749
// "assigns", which is handled by
736750
// `walk_pat`:
737751
self.walk_expr(&**expr);
738-
let init_cmt = self.mc.cat_expr(&**expr);
752+
let init_cmt = return_if_err!(self.mc.cat_expr(&**expr));
739753
self.walk_irrefutable_pat(init_cmt, &*local.pat);
740754
}
741755
}
@@ -769,7 +783,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
769783
None => { return; }
770784
};
771785

772-
let with_cmt = self.mc.cat_expr(&*with_expr);
786+
let with_cmt = return_if_err!(self.mc.cat_expr(&*with_expr));
773787

774788
// Select just those fields of the `with`
775789
// expression that will actually be used
@@ -824,7 +838,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
824838
// rvalue.
825839
debug!("walk_adjustment(AutoAddEnv|AdjustReifyFnPointer)");
826840
let cmt_unadjusted =
827-
self.mc.cat_expr_unadjusted(expr);
841+
return_if_err!(self.mc.cat_expr_unadjusted(expr));
828842
self.delegate_consume(expr.id, expr.span, cmt_unadjusted);
829843
}
830844
ty::AdjustDerefRef(ty::AutoDerefRef {
@@ -858,7 +872,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
858872
match self.typer.node_method_ty(deref_id) {
859873
None => {}
860874
Some(method_ty) => {
861-
let cmt = self.mc.cat_expr_autoderefd(expr, i);
875+
let cmt = return_if_err!(self.mc.cat_expr_autoderefd(expr, i));
862876
let self_ty = ty::ty_fn_args(method_ty)[0];
863877
let (m, r) = match self_ty.sty {
864878
ty::ty_rptr(r, ref m) => (m.mutbl, r),
@@ -888,14 +902,15 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
888902
assert!(n == 1, format!("Expected exactly 1 deref with Uniq \
889903
AutoRefs, found: {}", n));
890904
let cmt_unadjusted =
891-
self.mc.cat_expr_unadjusted(expr);
905+
return_if_err!(self.mc.cat_expr_unadjusted(expr));
892906
self.delegate_consume(expr.id, expr.span, cmt_unadjusted);
893907
return;
894908
}
895909
_ => {}
896910
}
897911

898-
let cmt_derefd = self.mc.cat_expr_autoderefd(expr, n);
912+
let cmt_derefd = return_if_err!(
913+
self.mc.cat_expr_autoderefd(expr, n));
899914
debug!("walk_adjustment: cmt_derefd={}",
900915
cmt_derefd.repr(self.tcx()));
901916

@@ -988,7 +1003,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
9881003
mode: &mut TrackMatchMode<Span>) {
9891004
debug!("determine_pat_move_mode cmt_discr={} pat={}", cmt_discr.repr(self.tcx()),
9901005
pat.repr(self.tcx()));
991-
self.mc.cat_pattern(cmt_discr, pat, |_mc, cmt_pat, pat| {
1006+
return_if_err!(self.mc.cat_pattern(cmt_discr, pat, |_mc, cmt_pat, pat| {
9921007
let tcx = self.typer.tcx();
9931008
let def_map = &self.typer.tcx().def_map;
9941009
if pat_util::pat_is_binding(def_map, pat) {
@@ -1011,7 +1026,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
10111026
}
10121027
}
10131028
}
1014-
});
1029+
}));
10151030
}
10161031

10171032
/// The core driver for walking a pattern; `match_mode` must be
@@ -1028,8 +1043,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
10281043
let typer = self.typer;
10291044
let def_map = &self.typer.tcx().def_map;
10301045
let delegate = &mut self.delegate;
1031-
let param_env = self.param_env;
1032-
mc.cat_pattern(cmt_discr.clone(), pat, |mc, cmt_pat, pat| {
1046+
return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |mc, cmt_pat, pat| {
10331047
if pat_util::pat_is_binding(def_map, pat) {
10341048
let tcx = typer.tcx();
10351049

@@ -1039,7 +1053,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
10391053
match_mode);
10401054

10411055
// pat_ty: the type of the binding being produced.
1042-
let pat_ty = typer.node_ty(pat.id);
1056+
let pat_ty = return_if_err!(typer.node_ty(pat.id));
10431057

10441058
// Each match binding is effectively an assignment to the
10451059
// binding being produced.
@@ -1080,7 +1094,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
10801094
// matched.
10811095

10821096
let (slice_cmt, slice_mutbl, slice_r) =
1083-
mc.cat_slice_pattern(cmt_pat, &**slice_pat);
1097+
return_if_err!(mc.cat_slice_pattern(cmt_pat, &**slice_pat));
10841098

10851099
// Note: We declare here that the borrow
10861100
// occurs upon entering the `[...]`
@@ -1110,13 +1124,13 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
11101124
_ => { }
11111125
}
11121126
}
1113-
});
1127+
}));
11141128

11151129
// Do a second pass over the pattern, calling `matched_pat` on
11161130
// the interior nodes (enum variants and structs), as opposed
11171131
// to the above loop's visit of than the bindings that form
11181132
// the leaves of the pattern tree structure.
1119-
mc.cat_pattern(cmt_discr, pat, |mc, cmt_pat, pat| {
1133+
return_if_err!(mc.cat_pattern(cmt_discr, pat, |mc, cmt_pat, pat| {
11201134
let def_map = def_map.borrow();
11211135
let tcx = typer.tcx();
11221136

@@ -1197,7 +1211,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
11971211
// cases either.
11981212
}
11991213
}
1200-
});
1214+
}));
12011215
}
12021216

12031217
fn walk_captures(&mut self, closure_expr: &ast::Expr) {
@@ -1221,9 +1235,9 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
12211235
freevars: &[ty::Freevar]) {
12221236
for freevar in freevars.iter() {
12231237
let id_var = freevar.def.def_id().node;
1224-
let cmt_var = self.cat_captured_var(closure_expr.id,
1225-
closure_expr.span,
1226-
freevar.def);
1238+
let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.id,
1239+
closure_expr.span,
1240+
freevar.def));
12271241

12281242
// Lookup the kind of borrow the callee requires, as
12291243
// inferred by regionbk
@@ -1244,11 +1258,10 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
12441258
closure_expr: &ast::Expr,
12451259
freevars: &[ty::Freevar]) {
12461260
for freevar in freevars.iter() {
1247-
let cmt_var = self.cat_captured_var(closure_expr.id,
1248-
closure_expr.span,
1249-
freevar.def);
1250-
let mode = copy_or_move(self.tcx(), cmt_var.ty,
1251-
self.param_env, CaptureMove);
1261+
let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.id,
1262+
closure_expr.span,
1263+
freevar.def));
1264+
let mode = copy_or_move(self.typer, &cmt_var, CaptureMove);
12521265
self.delegate.consume(closure_expr.id, freevar.span, cmt_var, mode);
12531266
}
12541267
}
@@ -1257,11 +1270,11 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
12571270
closure_id: ast::NodeId,
12581271
closure_span: Span,
12591272
upvar_def: def::Def)
1260-
-> mc::cmt<'tcx> {
1273+
-> mc::McResult<mc::cmt<'tcx>> {
12611274
// Create the cmt for the variable being borrowed, from the
12621275
// caller's perspective
12631276
let var_id = upvar_def.def_id().node;
1264-
let var_ty = self.typer.node_ty(var_id);
1277+
let var_ty = try!(self.typer.node_ty(var_id));
12651278
self.mc.cat_def(closure_id, closure_span, var_ty, upvar_def)
12661279
}
12671280
}

0 commit comments

Comments
 (0)