about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAriel Ben-Yehuda <arielb1@mail.tau.ac.il>2016-05-17 16:45:02 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2016-06-10 01:06:37 +0300
commite783a0a5e39d5ae2fa147508197d09a51530fae8 (patch)
tree8091cdf9422e139f634fb5624e7cbd86eb4fa3e3
parent392b6e7c8150ca852138212457a0dfae25eaa9b2 (diff)
make all pattern bindings with the same name resolve to the first one
This simplifies the code considerably, removing one of the
last uses of hygienic matching out of resolution.
-rw-r--r--src/librustc/hir/pat_util.rs10
-rw-r--r--src/librustc_mir/hair/cx/expr.rs15
-rw-r--r--src/librustc_mir/hair/cx/pattern.rs17
-rw-r--r--src/librustc_typeck/check/_match.rs42
-rw-r--r--src/librustc_typeck/check/mod.rs15
5 files changed, 22 insertions, 77 deletions
diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs
index 27530d8c75d..6405be7455d 100644
--- a/src/librustc/hir/pat_util.rs
+++ b/src/librustc/hir/pat_util.rs
@@ -53,16 +53,6 @@ impl<T: ExactSizeIterator> 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 47f94e5b315..b5e2ce9de48 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 c1f3dc15623..89bd0fdf897 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<ast::Name, ast::NodeId>>,
 }
 
 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<ast::Name, ast::NodeId>>,
                          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<ast::Name, ast::NodeId>>)
+    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 ce8ac2a8dbc..bee0d6338d8 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<hir::FieldPat>],
                             etc: bool, expected: Ty<'tcx>) {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 5deef3bc19b..4dee1e43d16 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);