diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs index 27530d8c75d13..6405be7455dfe 100644 --- a/src/librustc/hir/pat_util.rs +++ b/src/librustc/hir/pat_util.rs @@ -53,16 +53,6 @@ impl EnumerateAndAdjustIterator for T { } } -// This is used because same-named variables in alternative patterns need to -// use the NodeId of their namesake in the first pattern. -pub fn pat_id_map(pat: &hir::Pat) -> PatIdMap { - let mut map = FnvHashMap(); - pat_bindings(pat, |_bm, p_id, _s, path1| { - map.insert(path1.node, p_id); - }); - map -} - pub fn pat_is_refutable(dm: &DefMap, pat: &hir::Pat) -> bool { match pat.node { PatKind::Lit(_) | PatKind::Range(_, _) | PatKind::QPath(..) => true, diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 47f94e5b31549..b5e2ce9de4836 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -9,7 +9,6 @@ // except according to those terms. use hair::*; -use rustc_data_structures::fnv::FnvHashMap; use rustc_data_structures::indexed_vec::Idx; use rustc_const_math::ConstInt; use hair::cx::Cx; @@ -20,7 +19,6 @@ use rustc::hir::def::Def; use rustc::middle::const_val::ConstVal; use rustc_const_eval as const_eval; use rustc::middle::region::CodeExtent; -use rustc::hir::pat_util; use rustc::ty::{self, VariantDef, Ty}; use rustc::ty::cast::CastKind as TyCastKind; use rustc::mir::repr::*; @@ -652,19 +650,8 @@ fn to_borrow_kind(m: hir::Mutability) -> BorrowKind { fn convert_arm<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, arm: &'tcx hir::Arm) -> Arm<'tcx> { - let mut map; - let opt_map = if arm.pats.len() == 1 { - None - } else { - map = FnvHashMap(); - pat_util::pat_bindings(&arm.pats[0], |_, p_id, _, path| { - map.insert(path.node, p_id); - }); - Some(&map) - }; - Arm { - patterns: arm.pats.iter().map(|p| cx.refutable_pat(opt_map, p)).collect(), + patterns: arm.pats.iter().map(|p| cx.refutable_pat(p)).collect(), guard: arm.guard.to_ref(), body: arm.body.to_ref(), } diff --git a/src/librustc_mir/hair/cx/pattern.rs b/src/librustc_mir/hair/cx/pattern.rs index c1f3dc1562395..89bd0fdf89760 100644 --- a/src/librustc_mir/hair/cx/pattern.rs +++ b/src/librustc_mir/hair/cx/pattern.rs @@ -10,7 +10,6 @@ use hair::*; use hair::cx::Cx; -use rustc_data_structures::fnv::FnvHashMap; use rustc_data_structures::indexed_vec::Idx; use rustc_const_eval as const_eval; use rustc::hir::def::Def; @@ -18,7 +17,6 @@ use rustc::hir::pat_util::{EnumerateAndAdjustIterator, pat_is_resolved_const}; use rustc::ty::{self, Ty}; use rustc::mir::repr::*; use rustc::hir::{self, PatKind}; -use syntax::ast; use syntax::codemap::Span; use syntax::ptr::P; @@ -37,29 +35,25 @@ use syntax::ptr::P; /// ``` struct PatCx<'patcx, 'cx: 'patcx, 'gcx: 'cx+'tcx, 'tcx: 'cx> { cx: &'patcx mut Cx<'cx, 'gcx, 'tcx>, - binding_map: Option<&'patcx FnvHashMap>, } impl<'cx, 'gcx, 'tcx> Cx<'cx, 'gcx, 'tcx> { pub fn irrefutable_pat(&mut self, pat: &hir::Pat) -> Pattern<'tcx> { - PatCx::new(self, None).to_pattern(pat) + PatCx::new(self).to_pattern(pat) } pub fn refutable_pat(&mut self, - binding_map: Option<&FnvHashMap>, pat: &hir::Pat) -> Pattern<'tcx> { - PatCx::new(self, binding_map).to_pattern(pat) + PatCx::new(self).to_pattern(pat) } } impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> { - fn new(cx: &'patcx mut Cx<'cx, 'gcx, 'tcx>, - binding_map: Option<&'patcx FnvHashMap>) + fn new(cx: &'patcx mut Cx<'cx, 'gcx, 'tcx>) -> PatCx<'patcx, 'cx, 'gcx, 'tcx> { PatCx { cx: cx, - binding_map: binding_map, } } @@ -168,10 +162,7 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> { } PatKind::Binding(bm, ref ident, ref sub) => { - let id = match self.binding_map { - None => pat.id, - Some(ref map) => map[&ident.node], - }; + let id = self.cx.tcx.def_map.borrow()[&pat.id].full_def().var_id(); let var_ty = self.cx.tcx.node_id_to_type(pat.id); let region = match var_ty.sty { ty::TyRef(&r, _) => Some(r), diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index ce8ac2a8dbcd3..bee0d6338d852 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -10,7 +10,6 @@ use hir::def::Def; use rustc::infer::{self, InferOk, TypeOrigin}; -use hir::pat_util::{PatIdMap, pat_id_map}; use hir::pat_util::{EnumerateAndAdjustIterator, pat_is_resolved_const}; use rustc::ty::subst::Substs; use rustc::ty::{self, Ty, TypeFoldable, LvaluePreference}; @@ -21,7 +20,6 @@ use session::Session; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::cmp; -use std::ops::Deref; use syntax::ast; use syntax::codemap::{Span, Spanned}; use syntax::ptr::P; @@ -29,18 +27,6 @@ use syntax::ptr::P; use rustc::hir::{self, PatKind}; use rustc::hir::print as pprust; -pub struct PatCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { - pub fcx: &'a FnCtxt<'a, 'gcx, 'tcx>, - pub map: PatIdMap, -} - -impl<'a, 'gcx, 'tcx> Deref for PatCtxt<'a, 'gcx, 'tcx> { - type Target = FnCtxt<'a, 'gcx, 'tcx>; - fn deref(&self) -> &Self::Target { - self.fcx - } -} - // This function exists due to the warning "diagnostic code E0164 already used" fn bad_struct_kind_err(sess: &Session, pat: &hir::Pat, path: &hir::Path, lint: bool) { let name = pprust::path_to_string(path); @@ -55,7 +41,7 @@ fn bad_struct_kind_err(sess: &Session, pat: &hir::Pat, path: &hir::Path, lint: b } } -impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, 'tcx> { +impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub fn check_pat(&self, pat: &'gcx hir::Pat, expected: Ty<'tcx>) { let tcx = self.tcx; @@ -194,15 +180,19 @@ impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, 'tcx> { // if there are multiple arms, make sure they all agree on // what the type of the binding `x` ought to be - if let Some(&canon_id) = self.map.get(&path.node) { - if canon_id != pat.id { - let ct = self.local_ty(pat.span, canon_id); - self.demand_eqtype(pat.span, ct, typ); + match tcx.def_map.borrow()[&pat.id].full_def() { + Def::Err => {} + Def::Local(_, var_id) => { + if var_id != pat.id { + let vt = self.local_ty(pat.span, var_id); + self.demand_eqtype(pat.span, vt, typ); + } } + d => bug!("bad def for pattern binding `{:?}`", d) + } - if let Some(ref p) = *sub { - self.check_pat(&p, expected); - } + if let Some(ref p) = *sub { + self.check_pat(&p, expected); } } PatKind::TupleStruct(ref path, ref subpats, ddpos) => { @@ -476,12 +466,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Typecheck the patterns first, so that we get types for all the // bindings. for arm in arms { - let pcx = PatCtxt { - fcx: self, - map: pat_id_map(&arm.pats[0]), - }; for p in &arm.pats { - pcx.check_pat(&p, discrim_ty); + self.check_pat(&p, discrim_ty); } } @@ -566,7 +552,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } -impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, 'tcx> { +impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub fn check_pat_struct(&self, pat: &'gcx hir::Pat, path: &hir::Path, fields: &'gcx [Spanned], etc: bool, expected: Ty<'tcx>) { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 5deef3bc19b99..4dee1e43d16ab 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -81,14 +81,13 @@ pub use self::compare_method::{compare_impl_method, compare_const_impl}; use self::TupleArgumentsFlag::*; use astconv::{AstConv, ast_region_to_region, PathParamMode}; -use check::_match::PatCtxt; use dep_graph::DepNode; use fmt_macros::{Parser, Piece, Position}; use middle::cstore::LOCAL_CRATE; use hir::def::{self, Def}; use hir::def_id::DefId; use rustc::infer::{self, InferCtxt, InferOk, TypeOrigin, TypeTrace, type_variable}; -use hir::pat_util::{self, pat_id_map}; +use hir::pat_util::{self}; use rustc::ty::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace}; use rustc::traits::{self, ProjectionMode}; use rustc::ty::{GenericPredicates, TypeScheme}; @@ -672,11 +671,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, }); // Check the pattern. - let pcx = PatCtxt { - fcx: &fcx, - map: pat_id_map(&input.pat), - }; - pcx.check_pat(&input.pat, *arg_ty); + fcx.check_pat(&input.pat, *arg_ty); } visit.visit_block(body); @@ -3786,11 +3781,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } - let pcx = PatCtxt { - fcx: self, - map: pat_id_map(&local.pat), - }; - pcx.check_pat(&local.pat, t); + self.check_pat(&local.pat, t); let pat_ty = self.node_ty(local.pat.id); if pat_ty.references_error() { self.write_ty(local.id, pat_ty);