Skip to content

Commit cf46820

Browse files
committed
Refactor away some functions from hir::pat_util
1 parent 216f5fb commit cf46820

File tree

17 files changed

+168
-255
lines changed

17 files changed

+168
-255
lines changed

src/librustc/cfg/construct.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -456,8 +456,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
456456
// Visit the guard expression
457457
let guard_exit = self.expr(&guard, guard_start);
458458

459-
let this_has_bindings = pat_util::pat_contains_bindings_or_wild(
460-
&self.tcx.def_map.borrow(), &pat);
459+
let this_has_bindings = pat_util::pat_contains_bindings_or_wild(&pat);
461460

462461
// If both this pattern and the previous pattern
463462
// were free of bindings, they must consist only

src/librustc/hir/mod.rs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -524,14 +524,7 @@ pub enum PatKind {
524524
/// Represents a wildcard pattern (`_`)
525525
Wild,
526526

527-
/// A `PatKind::Ident` may either be a new bound variable,
528-
/// or a unit struct/variant pattern, or a const pattern (in the last two cases
529-
/// the third field must be `None`).
530-
///
531-
/// In the unit or const pattern case, the parser can't determine
532-
/// which it is. The resolver determines this, and
533-
/// records this pattern's `NodeId` in an auxiliary
534-
/// set (of "PatIdents that refer to unit patterns or constants").
527+
/// A fresh binding `ref mut binding @ OPT_SUBPATTERN`.
535528
Binding(BindingMode, Spanned<Name>, Option<P<Pat>>),
536529

537530
/// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
@@ -547,10 +540,8 @@ pub enum PatKind {
547540
/// Such pattern can be resolved to a unit struct/variant or a constant.
548541
Path(Path),
549542

550-
/// An associated const named using the qualified path `<T>::CONST` or
551-
/// `<T as Trait>::CONST`. Associated consts from inherent impls can be
552-
/// referred to as simply `T::CONST`, in which case they will end up as
553-
/// PatKind::Path, and the resolver will have to sort that out.
543+
/// A path pattern written in qualified form, i.e. `<T as Trait>::CONST` or `<T>::CONST`.
544+
/// Such patterns can only refer to associated constants at the moment.
554545
QPath(QSelf, Path),
555546

556547
/// A tuple pattern `(a, b)`.

src/librustc/hir/pat_util.rs

Lines changed: 27 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,12 @@
1010

1111
use hir::def::*;
1212
use hir::def_id::DefId;
13+
use hir::{self, PatKind};
1314
use ty::TyCtxt;
1415
use util::nodemap::FnvHashMap;
15-
1616
use syntax::ast;
17-
use hir::{self, PatKind};
18-
use syntax::codemap::{respan, Span, Spanned, DUMMY_SP};
17+
use syntax::codemap::{Span, Spanned, DUMMY_SP};
1918

20-
use std::cell::RefCell;
2119
use std::iter::{Enumerate, ExactSizeIterator};
2220

2321
pub type PatIdMap = FnvHashMap<ast::Name, ast::NodeId>;
@@ -57,9 +55,9 @@ impl<T: ExactSizeIterator> EnumerateAndAdjustIterator for T {
5755

5856
// This is used because same-named variables in alternative patterns need to
5957
// use the NodeId of their namesake in the first pattern.
60-
pub fn pat_id_map(dm: &RefCell<DefMap>, pat: &hir::Pat) -> PatIdMap {
58+
pub fn pat_id_map(pat: &hir::Pat) -> PatIdMap {
6159
let mut map = FnvHashMap();
62-
pat_bindings(dm, pat, |_bm, p_id, _s, path1| {
60+
pat_bindings(pat, |_bm, p_id, _s, path1| {
6361
map.insert(path1.node, p_id);
6462
});
6563
map
@@ -123,42 +121,25 @@ pub fn pat_is_resolved_const(dm: &DefMap, pat: &hir::Pat) -> bool {
123121
}
124122
}
125123

126-
pub fn pat_is_binding(_: &DefMap, pat: &hir::Pat) -> bool {
127-
match pat.node {
128-
PatKind::Binding(..) => true,
129-
_ => false
130-
}
131-
}
132-
133-
pub fn pat_is_binding_or_wild(_: &DefMap, pat: &hir::Pat) -> bool {
134-
match pat.node {
135-
PatKind::Binding(..) | PatKind::Wild => true,
136-
_ => false
137-
}
138-
}
139-
140-
/// Call `it` on every "binding" in a pattern, e.g., on `a` in
124+
/// Call `f` on every "binding" in a pattern, e.g., on `a` in
141125
/// `match foo() { Some(a) => (), None => () }`
142-
pub fn pat_bindings<I>(_: &RefCell<DefMap>, pat: &hir::Pat, mut it: I) where
143-
I: FnMut(hir::BindingMode, ast::NodeId, Span, &Spanned<ast::Name>),
126+
pub fn pat_bindings<F>(pat: &hir::Pat, mut f: F)
127+
where F: FnMut(hir::BindingMode, ast::NodeId, Span, &Spanned<ast::Name>),
144128
{
145129
pat.walk(|p| {
146-
match p.node {
147-
PatKind::Binding(binding_mode, ref pth, _) => {
148-
it(binding_mode, p.id, p.span, &respan(pth.span, pth.node));
149-
}
150-
_ => {}
130+
if let PatKind::Binding(binding_mode, ref pth, _) = p.node {
131+
f(binding_mode, p.id, p.span, pth);
151132
}
152133
true
153134
});
154135
}
155136

156137
/// Checks if the pattern contains any patterns that bind something to
157138
/// an ident, e.g. `foo`, or `Foo(foo)` or `foo @ Bar(..)`.
158-
pub fn pat_contains_bindings(dm: &DefMap, pat: &hir::Pat) -> bool {
139+
pub fn pat_contains_bindings(pat: &hir::Pat) -> bool {
159140
let mut contains_bindings = false;
160141
pat.walk(|p| {
161-
if pat_is_binding(dm, p) {
142+
if let PatKind::Binding(..) = p.node {
162143
contains_bindings = true;
163144
false // there's at least one binding, can short circuit now.
164145
} else {
@@ -170,28 +151,25 @@ pub fn pat_contains_bindings(dm: &DefMap, pat: &hir::Pat) -> bool {
170151

171152
/// Checks if the pattern contains any `ref` or `ref mut` bindings,
172153
/// and if yes whether its containing mutable ones or just immutables ones.
173-
pub fn pat_contains_ref_binding(dm: &RefCell<DefMap>, pat: &hir::Pat) -> Option<hir::Mutability> {
154+
pub fn pat_contains_ref_binding(pat: &hir::Pat) -> Option<hir::Mutability> {
174155
let mut result = None;
175-
pat_bindings(dm, pat, |mode, _, _, _| {
176-
match mode {
177-
hir::BindingMode::BindByRef(m) => {
178-
// Pick Mutable as maximum
179-
match result {
180-
None | Some(hir::MutImmutable) => result = Some(m),
181-
_ => (),
182-
}
156+
pat_bindings(pat, |mode, _, _, _| {
157+
if let hir::BindingMode::BindByRef(m) = mode {
158+
// Pick Mutable as maximum
159+
match result {
160+
None | Some(hir::MutImmutable) => result = Some(m),
161+
_ => (),
183162
}
184-
hir::BindingMode::BindByValue(_) => { }
185163
}
186164
});
187165
result
188166
}
189167

190168
/// Checks if the patterns for this arm contain any `ref` or `ref mut`
191169
/// bindings, and if yes whether its containing mutable ones or just immutables ones.
192-
pub fn arm_contains_ref_binding(dm: &RefCell<DefMap>, arm: &hir::Arm) -> Option<hir::Mutability> {
170+
pub fn arm_contains_ref_binding(arm: &hir::Arm) -> Option<hir::Mutability> {
193171
arm.pats.iter()
194-
.filter_map(|pat| pat_contains_ref_binding(dm, pat))
172+
.filter_map(|pat| pat_contains_ref_binding(pat))
195173
.max_by_key(|m| match *m {
196174
hir::MutMutable => 1,
197175
hir::MutImmutable => 0,
@@ -200,14 +178,15 @@ pub fn arm_contains_ref_binding(dm: &RefCell<DefMap>, arm: &hir::Arm) -> Option<
200178

201179
/// Checks if the pattern contains any patterns that bind something to
202180
/// an ident or wildcard, e.g. `foo`, or `Foo(_)`, `foo @ Bar(..)`,
203-
pub fn pat_contains_bindings_or_wild(dm: &DefMap, pat: &hir::Pat) -> bool {
181+
pub fn pat_contains_bindings_or_wild(pat: &hir::Pat) -> bool {
204182
let mut contains_bindings = false;
205183
pat.walk(|p| {
206-
if pat_is_binding_or_wild(dm, p) {
207-
contains_bindings = true;
208-
false // there's at least one binding/wildcard, can short circuit now.
209-
} else {
210-
true
184+
match p.node {
185+
PatKind::Binding(..) | PatKind::Wild => {
186+
contains_bindings = true;
187+
false // there's at least one binding/wildcard, can short circuit now.
188+
}
189+
_ => true
211190
}
212191
});
213192
contains_bindings

src/librustc/middle/expr_use_visitor.rs

Lines changed: 70 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -612,8 +612,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
612612
match local.init {
613613
None => {
614614
let delegate = &mut self.delegate;
615-
pat_util::pat_bindings(&self.mc.infcx.tcx.def_map, &local.pat,
616-
|_, id, span, _| {
615+
pat_util::pat_bindings(&local.pat, |_, id, span, _| {
617616
delegate.decl_without_init(id, span);
618617
})
619618
}
@@ -932,23 +931,16 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
932931
debug!("determine_pat_move_mode cmt_discr={:?} pat={:?}", cmt_discr,
933932
pat);
934933
return_if_err!(self.mc.cat_pattern(cmt_discr, pat, |_mc, cmt_pat, pat| {
935-
let def_map = &self.tcx().def_map;
936-
if pat_util::pat_is_binding(&def_map.borrow(), pat) {
937-
match pat.node {
938-
PatKind::Binding(hir::BindByRef(_), _, _) =>
939-
mode.lub(BorrowingMatch),
940-
PatKind::Binding(hir::BindByValue(_), _, _) => {
941-
match copy_or_move(self.mc.infcx, &cmt_pat, PatBindingMove) {
942-
Copy => mode.lub(CopyingMatch),
943-
Move(_) => mode.lub(MovingMatch),
944-
}
945-
}
946-
_ => {
947-
span_bug!(
948-
pat.span,
949-
"binding pattern not an identifier");
934+
match pat.node {
935+
PatKind::Binding(hir::BindByRef(..), _, _) =>
936+
mode.lub(BorrowingMatch),
937+
PatKind::Binding(hir::BindByValue(..), _, _) => {
938+
match copy_or_move(self.mc.infcx, &cmt_pat, PatBindingMove) {
939+
Copy => mode.lub(CopyingMatch),
940+
Move(..) => mode.lub(MovingMatch),
950941
}
951942
}
943+
_ => {}
952944
}
953945
}));
954946
}
@@ -968,83 +960,74 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
968960
let def_map = &self.tcx().def_map;
969961
let delegate = &mut self.delegate;
970962
return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |mc, cmt_pat, pat| {
971-
if pat_util::pat_is_binding(&def_map.borrow(), pat) {
972-
debug!("binding cmt_pat={:?} pat={:?} match_mode={:?}",
973-
cmt_pat,
974-
pat,
975-
match_mode);
976-
977-
// pat_ty: the type of the binding being produced.
978-
let pat_ty = return_if_err!(infcx.node_ty(pat.id));
979-
980-
// Each match binding is effectively an assignment to the
981-
// binding being produced.
982-
let def = def_map.borrow().get(&pat.id).unwrap().full_def();
983-
match mc.cat_def(pat.id, pat.span, pat_ty, def) {
984-
Ok(binding_cmt) => {
963+
match pat.node {
964+
PatKind::Binding(bmode, _, _) => {
965+
debug!("binding cmt_pat={:?} pat={:?} match_mode={:?}",
966+
cmt_pat,
967+
pat,
968+
match_mode);
969+
970+
// pat_ty: the type of the binding being produced.
971+
let pat_ty = return_if_err!(infcx.node_ty(pat.id));
972+
973+
// Each match binding is effectively an assignment to the
974+
// binding being produced.
975+
let def = def_map.borrow().get(&pat.id).unwrap().full_def();
976+
if let Ok(binding_cmt) = mc.cat_def(pat.id, pat.span, pat_ty, def) {
985977
delegate.mutate(pat.id, pat.span, binding_cmt, MutateMode::Init);
986978
}
987-
Err(_) => { }
988-
}
989979

990-
// It is also a borrow or copy/move of the value being matched.
991-
match pat.node {
992-
PatKind::Binding(hir::BindByRef(m), _, _) => {
993-
if let ty::TyRef(&r, _) = pat_ty.sty {
994-
let bk = ty::BorrowKind::from_mutbl(m);
995-
delegate.borrow(pat.id, pat.span, cmt_pat,
996-
r, bk, RefBinding);
980+
// It is also a borrow or copy/move of the value being matched.
981+
match bmode {
982+
hir::BindByRef(m) => {
983+
if let ty::TyRef(&r, _) = pat_ty.sty {
984+
let bk = ty::BorrowKind::from_mutbl(m);
985+
delegate.borrow(pat.id, pat.span, cmt_pat,
986+
r, bk, RefBinding);
987+
}
988+
}
989+
hir::BindByValue(..) => {
990+
let mode = copy_or_move(infcx, &cmt_pat, PatBindingMove);
991+
debug!("walk_pat binding consuming pat");
992+
delegate.consume_pat(pat, cmt_pat, mode);
997993
}
998-
}
999-
PatKind::Binding(hir::BindByValue(_), _, _) => {
1000-
let mode = copy_or_move(infcx, &cmt_pat, PatBindingMove);
1001-
debug!("walk_pat binding consuming pat");
1002-
delegate.consume_pat(pat, cmt_pat, mode);
1003-
}
1004-
_ => {
1005-
span_bug!(
1006-
pat.span,
1007-
"binding pattern not an identifier");
1008994
}
1009995
}
1010-
} else {
1011-
match pat.node {
1012-
PatKind::Vec(_, Some(ref slice_pat), _) => {
1013-
// The `slice_pat` here creates a slice into
1014-
// the original vector. This is effectively a
1015-
// borrow of the elements of the vector being
1016-
// matched.
1017-
1018-
let (slice_cmt, slice_mutbl, slice_r) =
1019-
return_if_err!(mc.cat_slice_pattern(cmt_pat, &slice_pat));
1020-
1021-
// Note: We declare here that the borrow
1022-
// occurs upon entering the `[...]`
1023-
// pattern. This implies that something like
1024-
// `[a; b]` where `a` is a move is illegal,
1025-
// because the borrow is already in effect.
1026-
// In fact such a move would be safe-ish, but
1027-
// it effectively *requires* that we use the
1028-
// nulling out semantics to indicate when a
1029-
// value has been moved, which we are trying
1030-
// to move away from. Otherwise, how can we
1031-
// indicate that the first element in the
1032-
// vector has been moved? Eventually, we
1033-
// could perhaps modify this rule to permit
1034-
// `[..a, b]` where `b` is a move, because in
1035-
// that case we can adjust the length of the
1036-
// original vec accordingly, but we'd have to
1037-
// make trans do the right thing, and it would
1038-
// only work for `Box<[T]>`s. It seems simpler
1039-
// to just require that people call
1040-
// `vec.pop()` or `vec.unshift()`.
1041-
let slice_bk = ty::BorrowKind::from_mutbl(slice_mutbl);
1042-
delegate.borrow(pat.id, pat.span,
1043-
slice_cmt, slice_r,
1044-
slice_bk, RefBinding);
1045-
}
1046-
_ => { }
996+
PatKind::Vec(_, Some(ref slice_pat), _) => {
997+
// The `slice_pat` here creates a slice into
998+
// the original vector. This is effectively a
999+
// borrow of the elements of the vector being
1000+
// matched.
1001+
1002+
let (slice_cmt, slice_mutbl, slice_r) =
1003+
return_if_err!(mc.cat_slice_pattern(cmt_pat, &slice_pat));
1004+
1005+
// Note: We declare here that the borrow
1006+
// occurs upon entering the `[...]`
1007+
// pattern. This implies that something like
1008+
// `[a; b]` where `a` is a move is illegal,
1009+
// because the borrow is already in effect.
1010+
// In fact such a move would be safe-ish, but
1011+
// it effectively *requires* that we use the
1012+
// nulling out semantics to indicate when a
1013+
// value has been moved, which we are trying
1014+
// to move away from. Otherwise, how can we
1015+
// indicate that the first element in the
1016+
// vector has been moved? Eventually, we
1017+
// could perhaps modify this rule to permit
1018+
// `[..a, b]` where `b` is a move, because in
1019+
// that case we can adjust the length of the
1020+
// original vec accordingly, but we'd have to
1021+
// make trans do the right thing, and it would
1022+
// only work for `Box<[T]>`s. It seems simpler
1023+
// to just require that people call
1024+
// `vec.pop()` or `vec.unshift()`.
1025+
let slice_bk = ty::BorrowKind::from_mutbl(slice_mutbl);
1026+
delegate.borrow(pat.id, pat.span,
1027+
slice_cmt, slice_r,
1028+
slice_bk, RefBinding);
10471029
}
1030+
_ => {}
10481031
}
10491032
}));
10501033

0 commit comments

Comments
 (0)