Skip to content

Commit e783a0a

Browse files
Ariel Ben-Yehudapetrochenkov
Ariel Ben-Yehuda
authored andcommitted
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.
1 parent 392b6e7 commit e783a0a

File tree

5 files changed

+22
-77
lines changed

5 files changed

+22
-77
lines changed

src/librustc/hir/pat_util.rs

-10
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,6 @@ impl<T: ExactSizeIterator> EnumerateAndAdjustIterator for T {
5353
}
5454
}
5555

56-
// This is used because same-named variables in alternative patterns need to
57-
// use the NodeId of their namesake in the first pattern.
58-
pub fn pat_id_map(pat: &hir::Pat) -> PatIdMap {
59-
let mut map = FnvHashMap();
60-
pat_bindings(pat, |_bm, p_id, _s, path1| {
61-
map.insert(path1.node, p_id);
62-
});
63-
map
64-
}
65-
6656
pub fn pat_is_refutable(dm: &DefMap, pat: &hir::Pat) -> bool {
6757
match pat.node {
6858
PatKind::Lit(_) | PatKind::Range(_, _) | PatKind::QPath(..) => true,

src/librustc_mir/hair/cx/expr.rs

+1-14
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
// except according to those terms.
1010

1111
use hair::*;
12-
use rustc_data_structures::fnv::FnvHashMap;
1312
use rustc_data_structures::indexed_vec::Idx;
1413
use rustc_const_math::ConstInt;
1514
use hair::cx::Cx;
@@ -20,7 +19,6 @@ use rustc::hir::def::Def;
2019
use rustc::middle::const_val::ConstVal;
2120
use rustc_const_eval as const_eval;
2221
use rustc::middle::region::CodeExtent;
23-
use rustc::hir::pat_util;
2422
use rustc::ty::{self, VariantDef, Ty};
2523
use rustc::ty::cast::CastKind as TyCastKind;
2624
use rustc::mir::repr::*;
@@ -652,19 +650,8 @@ fn to_borrow_kind(m: hir::Mutability) -> BorrowKind {
652650

653651
fn convert_arm<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
654652
arm: &'tcx hir::Arm) -> Arm<'tcx> {
655-
let mut map;
656-
let opt_map = if arm.pats.len() == 1 {
657-
None
658-
} else {
659-
map = FnvHashMap();
660-
pat_util::pat_bindings(&arm.pats[0], |_, p_id, _, path| {
661-
map.insert(path.node, p_id);
662-
});
663-
Some(&map)
664-
};
665-
666653
Arm {
667-
patterns: arm.pats.iter().map(|p| cx.refutable_pat(opt_map, p)).collect(),
654+
patterns: arm.pats.iter().map(|p| cx.refutable_pat(p)).collect(),
668655
guard: arm.guard.to_ref(),
669656
body: arm.body.to_ref(),
670657
}

src/librustc_mir/hair/cx/pattern.rs

+4-13
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,13 @@
1010

1111
use hair::*;
1212
use hair::cx::Cx;
13-
use rustc_data_structures::fnv::FnvHashMap;
1413
use rustc_data_structures::indexed_vec::Idx;
1514
use rustc_const_eval as const_eval;
1615
use rustc::hir::def::Def;
1716
use rustc::hir::pat_util::{EnumerateAndAdjustIterator, pat_is_resolved_const};
1817
use rustc::ty::{self, Ty};
1918
use rustc::mir::repr::*;
2019
use rustc::hir::{self, PatKind};
21-
use syntax::ast;
2220
use syntax::codemap::Span;
2321
use syntax::ptr::P;
2422

@@ -37,29 +35,25 @@ use syntax::ptr::P;
3735
/// ```
3836
struct PatCx<'patcx, 'cx: 'patcx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
3937
cx: &'patcx mut Cx<'cx, 'gcx, 'tcx>,
40-
binding_map: Option<&'patcx FnvHashMap<ast::Name, ast::NodeId>>,
4138
}
4239

4340
impl<'cx, 'gcx, 'tcx> Cx<'cx, 'gcx, 'tcx> {
4441
pub fn irrefutable_pat(&mut self, pat: &hir::Pat) -> Pattern<'tcx> {
45-
PatCx::new(self, None).to_pattern(pat)
42+
PatCx::new(self).to_pattern(pat)
4643
}
4744

4845
pub fn refutable_pat(&mut self,
49-
binding_map: Option<&FnvHashMap<ast::Name, ast::NodeId>>,
5046
pat: &hir::Pat)
5147
-> Pattern<'tcx> {
52-
PatCx::new(self, binding_map).to_pattern(pat)
48+
PatCx::new(self).to_pattern(pat)
5349
}
5450
}
5551

5652
impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
57-
fn new(cx: &'patcx mut Cx<'cx, 'gcx, 'tcx>,
58-
binding_map: Option<&'patcx FnvHashMap<ast::Name, ast::NodeId>>)
53+
fn new(cx: &'patcx mut Cx<'cx, 'gcx, 'tcx>)
5954
-> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
6055
PatCx {
6156
cx: cx,
62-
binding_map: binding_map,
6357
}
6458
}
6559

@@ -168,10 +162,7 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
168162
}
169163

170164
PatKind::Binding(bm, ref ident, ref sub) => {
171-
let id = match self.binding_map {
172-
None => pat.id,
173-
Some(ref map) => map[&ident.node],
174-
};
165+
let id = self.cx.tcx.def_map.borrow()[&pat.id].full_def().var_id();
175166
let var_ty = self.cx.tcx.node_id_to_type(pat.id);
176167
let region = match var_ty.sty {
177168
ty::TyRef(&r, _) => Some(r),

src/librustc_typeck/check/_match.rs

+14-28
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
use hir::def::Def;
1212
use rustc::infer::{self, InferOk, TypeOrigin};
13-
use hir::pat_util::{PatIdMap, pat_id_map};
1413
use hir::pat_util::{EnumerateAndAdjustIterator, pat_is_resolved_const};
1514
use rustc::ty::subst::Substs;
1615
use rustc::ty::{self, Ty, TypeFoldable, LvaluePreference};
@@ -21,26 +20,13 @@ use session::Session;
2120

2221
use std::collections::hash_map::Entry::{Occupied, Vacant};
2322
use std::cmp;
24-
use std::ops::Deref;
2523
use syntax::ast;
2624
use syntax::codemap::{Span, Spanned};
2725
use syntax::ptr::P;
2826

2927
use rustc::hir::{self, PatKind};
3028
use rustc::hir::print as pprust;
3129

32-
pub struct PatCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
33-
pub fcx: &'a FnCtxt<'a, 'gcx, 'tcx>,
34-
pub map: PatIdMap,
35-
}
36-
37-
impl<'a, 'gcx, 'tcx> Deref for PatCtxt<'a, 'gcx, 'tcx> {
38-
type Target = FnCtxt<'a, 'gcx, 'tcx>;
39-
fn deref(&self) -> &Self::Target {
40-
self.fcx
41-
}
42-
}
43-
4430
// This function exists due to the warning "diagnostic code E0164 already used"
4531
fn bad_struct_kind_err(sess: &Session, pat: &hir::Pat, path: &hir::Path, lint: bool) {
4632
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
5541
}
5642
}
5743

58-
impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, 'tcx> {
44+
impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
5945
pub fn check_pat(&self, pat: &'gcx hir::Pat, expected: Ty<'tcx>) {
6046
let tcx = self.tcx;
6147

@@ -194,15 +180,19 @@ impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, 'tcx> {
194180

195181
// if there are multiple arms, make sure they all agree on
196182
// what the type of the binding `x` ought to be
197-
if let Some(&canon_id) = self.map.get(&path.node) {
198-
if canon_id != pat.id {
199-
let ct = self.local_ty(pat.span, canon_id);
200-
self.demand_eqtype(pat.span, ct, typ);
183+
match tcx.def_map.borrow()[&pat.id].full_def() {
184+
Def::Err => {}
185+
Def::Local(_, var_id) => {
186+
if var_id != pat.id {
187+
let vt = self.local_ty(pat.span, var_id);
188+
self.demand_eqtype(pat.span, vt, typ);
189+
}
201190
}
191+
d => bug!("bad def for pattern binding `{:?}`", d)
192+
}
202193

203-
if let Some(ref p) = *sub {
204-
self.check_pat(&p, expected);
205-
}
194+
if let Some(ref p) = *sub {
195+
self.check_pat(&p, expected);
206196
}
207197
}
208198
PatKind::TupleStruct(ref path, ref subpats, ddpos) => {
@@ -476,12 +466,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
476466
// Typecheck the patterns first, so that we get types for all the
477467
// bindings.
478468
for arm in arms {
479-
let pcx = PatCtxt {
480-
fcx: self,
481-
map: pat_id_map(&arm.pats[0]),
482-
};
483469
for p in &arm.pats {
484-
pcx.check_pat(&p, discrim_ty);
470+
self.check_pat(&p, discrim_ty);
485471
}
486472
}
487473

@@ -566,7 +552,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
566552
}
567553
}
568554

569-
impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, 'tcx> {
555+
impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
570556
pub fn check_pat_struct(&self, pat: &'gcx hir::Pat,
571557
path: &hir::Path, fields: &'gcx [Spanned<hir::FieldPat>],
572558
etc: bool, expected: Ty<'tcx>) {

src/librustc_typeck/check/mod.rs

+3-12
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,13 @@ pub use self::compare_method::{compare_impl_method, compare_const_impl};
8181
use self::TupleArgumentsFlag::*;
8282

8383
use astconv::{AstConv, ast_region_to_region, PathParamMode};
84-
use check::_match::PatCtxt;
8584
use dep_graph::DepNode;
8685
use fmt_macros::{Parser, Piece, Position};
8786
use middle::cstore::LOCAL_CRATE;
8887
use hir::def::{self, Def};
8988
use hir::def_id::DefId;
9089
use rustc::infer::{self, InferCtxt, InferOk, TypeOrigin, TypeTrace, type_variable};
91-
use hir::pat_util::{self, pat_id_map};
90+
use hir::pat_util::{self};
9291
use rustc::ty::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace};
9392
use rustc::traits::{self, ProjectionMode};
9493
use rustc::ty::{GenericPredicates, TypeScheme};
@@ -672,11 +671,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
672671
});
673672

674673
// Check the pattern.
675-
let pcx = PatCtxt {
676-
fcx: &fcx,
677-
map: pat_id_map(&input.pat),
678-
};
679-
pcx.check_pat(&input.pat, *arg_ty);
674+
fcx.check_pat(&input.pat, *arg_ty);
680675
}
681676

682677
visit.visit_block(body);
@@ -3786,11 +3781,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
37863781
}
37873782
}
37883783

3789-
let pcx = PatCtxt {
3790-
fcx: self,
3791-
map: pat_id_map(&local.pat),
3792-
};
3793-
pcx.check_pat(&local.pat, t);
3784+
self.check_pat(&local.pat, t);
37943785
let pat_ty = self.node_ty(local.pat.id);
37953786
if pat_ty.references_error() {
37963787
self.write_ty(local.id, pat_ty);

0 commit comments

Comments
 (0)