Skip to content

Commit b00050f

Browse files
committed
Add more safeguards to "missing binding mode" errors
1 parent 998141f commit b00050f

File tree

5 files changed

+67
-61
lines changed

5 files changed

+67
-61
lines changed

src/librustc/middle/expr_use_visitor.rs

+28-25
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
840840
fn walk_pat(&mut self, cmt_discr: mc::cmt<'tcx>, pat: &hir::Pat, match_mode: MatchMode) {
841841
debug!("walk_pat(cmt_discr={:?}, pat={:?})", cmt_discr, pat);
842842

843+
let tcx = self.tcx();
843844
let ExprUseVisitor { ref mc, ref mut delegate, param_env } = *self;
844845
return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |cmt_pat, pat| {
845846
if let PatKind::Binding(_, canonical_id, ..) = pat.node {
@@ -849,34 +850,36 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
849850
pat,
850851
match_mode,
851852
);
852-
let bm = *mc.tables.pat_binding_modes().get(pat.hir_id)
853-
.expect("missing binding mode");
854-
debug!("walk_pat: pat.hir_id={:?} bm={:?}", pat.hir_id, bm);
855-
856-
// pat_ty: the type of the binding being produced.
857-
let pat_ty = return_if_err!(mc.node_ty(pat.hir_id));
858-
debug!("walk_pat: pat_ty={:?}", pat_ty);
859-
860-
// Each match binding is effectively an assignment to the
861-
// binding being produced.
862-
let def = Def::Local(canonical_id);
863-
if let Ok(ref binding_cmt) = mc.cat_def(pat.hir_id, pat.span, pat_ty, def) {
864-
delegate.mutate(pat.id, pat.span, binding_cmt, MutateMode::Init);
865-
}
853+
if let Some(&bm) = mc.tables.pat_binding_modes().get(pat.hir_id) {
854+
debug!("walk_pat: pat.hir_id={:?} bm={:?}", pat.hir_id, bm);
855+
856+
// pat_ty: the type of the binding being produced.
857+
let pat_ty = return_if_err!(mc.node_ty(pat.hir_id));
858+
debug!("walk_pat: pat_ty={:?}", pat_ty);
859+
860+
// Each match binding is effectively an assignment to the
861+
// binding being produced.
862+
let def = Def::Local(canonical_id);
863+
if let Ok(ref binding_cmt) = mc.cat_def(pat.hir_id, pat.span, pat_ty, def) {
864+
delegate.mutate(pat.id, pat.span, binding_cmt, MutateMode::Init);
865+
}
866866

867-
// It is also a borrow or copy/move of the value being matched.
868-
match bm {
869-
ty::BindByReference(m) => {
870-
if let ty::TyRef(r, _, _) = pat_ty.sty {
871-
let bk = ty::BorrowKind::from_mutbl(m);
872-
delegate.borrow(pat.id, pat.span, &cmt_pat, r, bk, RefBinding);
867+
// It is also a borrow or copy/move of the value being matched.
868+
match bm {
869+
ty::BindByReference(m) => {
870+
if let ty::TyRef(r, _, _) = pat_ty.sty {
871+
let bk = ty::BorrowKind::from_mutbl(m);
872+
delegate.borrow(pat.id, pat.span, &cmt_pat, r, bk, RefBinding);
873+
}
874+
}
875+
ty::BindByValue(..) => {
876+
let mode = copy_or_move(mc, param_env, &cmt_pat, PatBindingMove);
877+
debug!("walk_pat binding consuming pat");
878+
delegate.consume_pat(pat, &cmt_pat, mode);
873879
}
874880
}
875-
ty::BindByValue(..) => {
876-
let mode = copy_or_move(mc, param_env, &cmt_pat, PatBindingMove);
877-
debug!("walk_pat binding consuming pat");
878-
delegate.consume_pat(pat, &cmt_pat, mode);
879-
}
881+
} else {
882+
tcx.sess.delay_span_bug(pat.span, "missing binding mode");
880883
}
881884
}
882885
}));

src/librustc_borrowck/borrowck/unused.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,16 @@ impl<'a, 'tcx> UnusedMutCx<'a, 'tcx> {
5454

5555
// Skip anything that looks like `&foo` or `&mut foo`, only look
5656
// for by-value bindings
57-
let bm = match self.bccx.tables.pat_binding_modes().get(hir_id) {
58-
Some(&bm) => bm,
59-
None => span_bug!(span, "missing binding mode"),
60-
};
61-
match bm {
62-
ty::BindByValue(hir::MutMutable) => {}
63-
_ => return,
57+
if let Some(&bm) = self.bccx.tables.pat_binding_modes().get(hir_id) {
58+
match bm {
59+
ty::BindByValue(hir::MutMutable) => {}
60+
_ => return,
61+
}
62+
63+
mutables.entry(ident.name).or_insert(Vec::new()).push((hir_id, span));
64+
} else {
65+
tcx.sess.delay_span_bug(span, "missing binding mode");
6466
}
65-
66-
mutables.entry(ident.name).or_insert(Vec::new()).push((hir_id, span));
6767
});
6868
}
6969

src/librustc_mir/build/mod.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -541,13 +541,14 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
541541
if let hir::PatKind::Binding(_, _, ident, _) = pat.node {
542542
decl.debug_name = ident.name;
543543

544-
let bm = *hir.tables.pat_binding_modes()
545-
.get(pat.hir_id)
546-
.expect("missing binding mode");
547-
if bm == ty::BindByValue(hir::MutMutable) {
548-
decl.mutability = Mutability::Mut;
544+
if let Some(&bm) = hir.tables.pat_binding_modes().get(pat.hir_id) {
545+
if bm == ty::BindByValue(hir::MutMutable) {
546+
decl.mutability = Mutability::Mut;
547+
} else {
548+
decl.mutability = Mutability::Not;
549+
}
549550
} else {
550-
decl.mutability = Mutability::Not;
551+
tcx.sess.delay_span_bug(pat.span, "missing binding mode");
551552
}
552553
}
553554
}

src/librustc_mir/hair/pattern/check_match.rs

+16-16
Original file line numberDiff line numberDiff line change
@@ -516,12 +516,12 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor,
516516
let mut by_ref_span = None;
517517
for pat in pats {
518518
pat.each_binding(|_, hir_id, span, _path| {
519-
let bm = *cx.tables
520-
.pat_binding_modes()
521-
.get(hir_id)
522-
.expect("missing binding mode");
523-
if let ty::BindByReference(..) = bm {
524-
by_ref_span = Some(span);
519+
if let Some(&bm) = cx.tables.pat_binding_modes().get(hir_id) {
520+
if let ty::BindByReference(..) = bm {
521+
by_ref_span = Some(span);
522+
}
523+
} else {
524+
cx.tcx.sess.delay_span_bug(pat.span, "missing binding mode");
525525
}
526526
})
527527
}
@@ -552,18 +552,18 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor,
552552
for pat in pats {
553553
pat.walk(|p| {
554554
if let PatKind::Binding(_, _, _, ref sub) = p.node {
555-
let bm = *cx.tables
556-
.pat_binding_modes()
557-
.get(p.hir_id)
558-
.expect("missing binding mode");
559-
match bm {
560-
ty::BindByValue(..) => {
561-
let pat_ty = cx.tables.node_id_to_type(p.hir_id);
562-
if pat_ty.moves_by_default(cx.tcx, cx.param_env, pat.span) {
563-
check_move(p, sub.as_ref().map(|p| &**p));
555+
if let Some(&bm) = cx.tables.pat_binding_modes().get(p.hir_id) {
556+
match bm {
557+
ty::BindByValue(..) => {
558+
let pat_ty = cx.tables.node_id_to_type(p.hir_id);
559+
if pat_ty.moves_by_default(cx.tcx, cx.param_env, pat.span) {
560+
check_move(p, sub.as_ref().map(|p| &**p));
561+
}
564562
}
563+
_ => {}
565564
}
566-
_ => {}
565+
} else {
566+
cx.tcx.sess.delay_span_bug(pat.span, "missing binding mode");
567567
}
568568
}
569569
true

src/librustc_typeck/check/regionck.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -1039,11 +1039,13 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
10391039
match sub_pat.node {
10401040
// `ref x` pattern
10411041
PatKind::Binding(..) => {
1042-
let bm = *mc.tables.pat_binding_modes().get(sub_pat.hir_id)
1043-
.expect("missing binding mode");
1044-
if let ty::BindByReference(mutbl) = bm {
1045-
self.link_region_from_node_type(sub_pat.span, sub_pat.hir_id,
1046-
mutbl, &sub_cmt);
1042+
if let Some(&bm) = mc.tables.pat_binding_modes().get(sub_pat.hir_id) {
1043+
if let ty::BindByReference(mutbl) = bm {
1044+
self.link_region_from_node_type(sub_pat.span, sub_pat.hir_id,
1045+
mutbl, &sub_cmt);
1046+
}
1047+
} else {
1048+
self.tcx.sess.delay_span_bug(sub_pat.span, "missing binding mode");
10471049
}
10481050
}
10491051
_ => {}

0 commit comments

Comments
 (0)