Add more safeguards to "missing binding mode" errors
This commit is contained in:
parent
998141f8ef
commit
b00050f4cf
@ -840,6 +840,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
||||
fn walk_pat(&mut self, cmt_discr: mc::cmt<'tcx>, pat: &hir::Pat, match_mode: MatchMode) {
|
||||
debug!("walk_pat(cmt_discr={:?}, pat={:?})", cmt_discr, pat);
|
||||
|
||||
let tcx = self.tcx();
|
||||
let ExprUseVisitor { ref mc, ref mut delegate, param_env } = *self;
|
||||
return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |cmt_pat, pat| {
|
||||
if let PatKind::Binding(_, canonical_id, ..) = pat.node {
|
||||
@ -849,34 +850,36 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
||||
pat,
|
||||
match_mode,
|
||||
);
|
||||
let bm = *mc.tables.pat_binding_modes().get(pat.hir_id)
|
||||
.expect("missing binding mode");
|
||||
debug!("walk_pat: pat.hir_id={:?} bm={:?}", pat.hir_id, bm);
|
||||
if let Some(&bm) = mc.tables.pat_binding_modes().get(pat.hir_id) {
|
||||
debug!("walk_pat: pat.hir_id={:?} bm={:?}", pat.hir_id, bm);
|
||||
|
||||
// pat_ty: the type of the binding being produced.
|
||||
let pat_ty = return_if_err!(mc.node_ty(pat.hir_id));
|
||||
debug!("walk_pat: pat_ty={:?}", pat_ty);
|
||||
// pat_ty: the type of the binding being produced.
|
||||
let pat_ty = return_if_err!(mc.node_ty(pat.hir_id));
|
||||
debug!("walk_pat: pat_ty={:?}", pat_ty);
|
||||
|
||||
// Each match binding is effectively an assignment to the
|
||||
// binding being produced.
|
||||
let def = Def::Local(canonical_id);
|
||||
if let Ok(ref binding_cmt) = mc.cat_def(pat.hir_id, pat.span, pat_ty, def) {
|
||||
delegate.mutate(pat.id, pat.span, binding_cmt, MutateMode::Init);
|
||||
}
|
||||
// Each match binding is effectively an assignment to the
|
||||
// binding being produced.
|
||||
let def = Def::Local(canonical_id);
|
||||
if let Ok(ref binding_cmt) = mc.cat_def(pat.hir_id, pat.span, pat_ty, def) {
|
||||
delegate.mutate(pat.id, pat.span, binding_cmt, MutateMode::Init);
|
||||
}
|
||||
|
||||
// It is also a borrow or copy/move of the value being matched.
|
||||
match bm {
|
||||
ty::BindByReference(m) => {
|
||||
if let ty::TyRef(r, _, _) = pat_ty.sty {
|
||||
let bk = ty::BorrowKind::from_mutbl(m);
|
||||
delegate.borrow(pat.id, pat.span, &cmt_pat, r, bk, RefBinding);
|
||||
// It is also a borrow or copy/move of the value being matched.
|
||||
match bm {
|
||||
ty::BindByReference(m) => {
|
||||
if let ty::TyRef(r, _, _) = pat_ty.sty {
|
||||
let bk = ty::BorrowKind::from_mutbl(m);
|
||||
delegate.borrow(pat.id, pat.span, &cmt_pat, r, bk, RefBinding);
|
||||
}
|
||||
}
|
||||
ty::BindByValue(..) => {
|
||||
let mode = copy_or_move(mc, param_env, &cmt_pat, PatBindingMove);
|
||||
debug!("walk_pat binding consuming pat");
|
||||
delegate.consume_pat(pat, &cmt_pat, mode);
|
||||
}
|
||||
}
|
||||
ty::BindByValue(..) => {
|
||||
let mode = copy_or_move(mc, param_env, &cmt_pat, PatBindingMove);
|
||||
debug!("walk_pat binding consuming pat");
|
||||
delegate.consume_pat(pat, &cmt_pat, mode);
|
||||
}
|
||||
} else {
|
||||
tcx.sess.delay_span_bug(pat.span, "missing binding mode");
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
@ -54,16 +54,16 @@ impl<'a, 'tcx> UnusedMutCx<'a, 'tcx> {
|
||||
|
||||
// Skip anything that looks like `&foo` or `&mut foo`, only look
|
||||
// for by-value bindings
|
||||
let bm = match self.bccx.tables.pat_binding_modes().get(hir_id) {
|
||||
Some(&bm) => bm,
|
||||
None => span_bug!(span, "missing binding mode"),
|
||||
};
|
||||
match bm {
|
||||
ty::BindByValue(hir::MutMutable) => {}
|
||||
_ => return,
|
||||
}
|
||||
if let Some(&bm) = self.bccx.tables.pat_binding_modes().get(hir_id) {
|
||||
match bm {
|
||||
ty::BindByValue(hir::MutMutable) => {}
|
||||
_ => return,
|
||||
}
|
||||
|
||||
mutables.entry(ident.name).or_insert(Vec::new()).push((hir_id, span));
|
||||
mutables.entry(ident.name).or_insert(Vec::new()).push((hir_id, span));
|
||||
} else {
|
||||
tcx.sess.delay_span_bug(span, "missing binding mode");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -541,13 +541,14 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
|
||||
if let hir::PatKind::Binding(_, _, ident, _) = pat.node {
|
||||
decl.debug_name = ident.name;
|
||||
|
||||
let bm = *hir.tables.pat_binding_modes()
|
||||
.get(pat.hir_id)
|
||||
.expect("missing binding mode");
|
||||
if bm == ty::BindByValue(hir::MutMutable) {
|
||||
decl.mutability = Mutability::Mut;
|
||||
if let Some(&bm) = hir.tables.pat_binding_modes().get(pat.hir_id) {
|
||||
if bm == ty::BindByValue(hir::MutMutable) {
|
||||
decl.mutability = Mutability::Mut;
|
||||
} else {
|
||||
decl.mutability = Mutability::Not;
|
||||
}
|
||||
} else {
|
||||
decl.mutability = Mutability::Not;
|
||||
tcx.sess.delay_span_bug(pat.span, "missing binding mode");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -516,12 +516,12 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor,
|
||||
let mut by_ref_span = None;
|
||||
for pat in pats {
|
||||
pat.each_binding(|_, hir_id, span, _path| {
|
||||
let bm = *cx.tables
|
||||
.pat_binding_modes()
|
||||
.get(hir_id)
|
||||
.expect("missing binding mode");
|
||||
if let ty::BindByReference(..) = bm {
|
||||
by_ref_span = Some(span);
|
||||
if let Some(&bm) = cx.tables.pat_binding_modes().get(hir_id) {
|
||||
if let ty::BindByReference(..) = bm {
|
||||
by_ref_span = Some(span);
|
||||
}
|
||||
} else {
|
||||
cx.tcx.sess.delay_span_bug(pat.span, "missing binding mode");
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -552,18 +552,18 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor,
|
||||
for pat in pats {
|
||||
pat.walk(|p| {
|
||||
if let PatKind::Binding(_, _, _, ref sub) = p.node {
|
||||
let bm = *cx.tables
|
||||
.pat_binding_modes()
|
||||
.get(p.hir_id)
|
||||
.expect("missing binding mode");
|
||||
match bm {
|
||||
ty::BindByValue(..) => {
|
||||
let pat_ty = cx.tables.node_id_to_type(p.hir_id);
|
||||
if pat_ty.moves_by_default(cx.tcx, cx.param_env, pat.span) {
|
||||
check_move(p, sub.as_ref().map(|p| &**p));
|
||||
if let Some(&bm) = cx.tables.pat_binding_modes().get(p.hir_id) {
|
||||
match bm {
|
||||
ty::BindByValue(..) => {
|
||||
let pat_ty = cx.tables.node_id_to_type(p.hir_id);
|
||||
if pat_ty.moves_by_default(cx.tcx, cx.param_env, pat.span) {
|
||||
check_move(p, sub.as_ref().map(|p| &**p));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
_ => {}
|
||||
} else {
|
||||
cx.tcx.sess.delay_span_bug(pat.span, "missing binding mode");
|
||||
}
|
||||
}
|
||||
true
|
||||
|
@ -1039,11 +1039,13 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
||||
match sub_pat.node {
|
||||
// `ref x` pattern
|
||||
PatKind::Binding(..) => {
|
||||
let bm = *mc.tables.pat_binding_modes().get(sub_pat.hir_id)
|
||||
.expect("missing binding mode");
|
||||
if let ty::BindByReference(mutbl) = bm {
|
||||
self.link_region_from_node_type(sub_pat.span, sub_pat.hir_id,
|
||||
mutbl, &sub_cmt);
|
||||
if let Some(&bm) = mc.tables.pat_binding_modes().get(sub_pat.hir_id) {
|
||||
if let ty::BindByReference(mutbl) = bm {
|
||||
self.link_region_from_node_type(sub_pat.span, sub_pat.hir_id,
|
||||
mutbl, &sub_cmt);
|
||||
}
|
||||
} else {
|
||||
self.tcx.sess.delay_span_bug(sub_pat.span, "missing binding mode");
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
Loading…
Reference in New Issue
Block a user