Skip to content

Commit a7b1ab5

Browse files
committed
Replace pat_adjust_pos with an iterator adapter
1 parent af5d4b8 commit a7b1ab5

File tree

11 files changed

+61
-66
lines changed

11 files changed

+61
-66
lines changed

src/librustc/hir/pat_util.rs

+24-12
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,40 @@ use hir::{self, PatKind};
1818
use syntax::codemap::{respan, Span, Spanned, DUMMY_SP};
1919

2020
use std::cell::RefCell;
21+
use std::iter::{Enumerate, ExactSizeIterator};
2122

2223
pub type PatIdMap = FnvHashMap<ast::Name, ast::NodeId>;
2324

24-
#[derive(Clone, Copy)]
25-
pub struct AdjustPos {
25+
pub struct EnumerateAndAdjust<I> {
26+
enumerate: Enumerate<I>,
2627
gap_pos: usize,
2728
gap_len: usize,
2829
}
2930

30-
impl FnOnce<(usize,)> for AdjustPos {
31-
type Output = usize;
32-
extern "rust-call" fn call_once(self, (i,): (usize,)) -> usize {
33-
if i < self.gap_pos { i } else { i + self.gap_len }
31+
impl<I> Iterator for EnumerateAndAdjust<I> where I: Iterator {
32+
type Item = (usize, <I as Iterator>::Item);
33+
34+
fn next(&mut self) -> Option<(usize, <I as Iterator>::Item)> {
35+
self.enumerate.next().map(|(i, elem)| {
36+
(if i < self.gap_pos { i } else { i + self.gap_len }, elem)
37+
})
3438
}
3539
}
3640

37-
// Returns a functional object used to adjust tuple pattern indexes. Example: for 5-tuple and
38-
// pattern (a, b, .., c) expected_len is 5, actual_len is 3 and gap_pos is Some(2).
39-
pub fn pat_adjust_pos(expected_len: usize, actual_len: usize, gap_pos: Option<usize>) -> AdjustPos {
40-
AdjustPos {
41-
gap_pos: if let Some(gap_pos) = gap_pos { gap_pos } else { expected_len },
42-
gap_len: expected_len - actual_len,
41+
pub trait EnumerateAndAdjustIterator {
42+
fn enumerate_and_adjust(self, expected_len: usize, gap_pos: Option<usize>)
43+
-> EnumerateAndAdjust<Self> where Self: Sized;
44+
}
45+
46+
impl<T: ExactSizeIterator> EnumerateAndAdjustIterator for T {
47+
fn enumerate_and_adjust(self, expected_len: usize, gap_pos: Option<usize>)
48+
-> EnumerateAndAdjust<Self> where Self: Sized {
49+
let actual_len = self.len();
50+
EnumerateAndAdjust {
51+
enumerate: self.enumerate(),
52+
gap_pos: if let Some(gap_pos) = gap_pos { gap_pos } else { expected_len },
53+
gap_len: expected_len - actual_len,
54+
}
4355
}
4456
}
4557

src/librustc/lib.rs

-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
#![feature(collections)]
3030
#![feature(const_fn)]
3131
#![feature(enumset)]
32-
#![feature(fn_traits)]
3332
#![feature(iter_arith)]
3433
#![feature(libc)]
3534
#![feature(nonzero)]
@@ -39,7 +38,6 @@
3938
#![feature(slice_patterns)]
4039
#![feature(staged_api)]
4140
#![feature(question_mark)]
42-
#![feature(unboxed_closures)]
4341
#![cfg_attr(test, feature(test))]
4442

4543
extern crate arena;

src/librustc/middle/mem_categorization.rs

+9-11
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ use ty::adjustment;
8080
use ty::{self, Ty, TyCtxt};
8181

8282
use hir::{MutImmutable, MutMutable, PatKind};
83-
use hir::pat_util::pat_adjust_pos;
83+
use hir::pat_util::EnumerateAndAdjustIterator;
8484
use hir;
8585
use syntax::ast;
8686
use syntax::codemap::Span;
@@ -1230,15 +1230,15 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
12301230
match opt_def {
12311231
Some(Def::Variant(enum_def, def_id)) => {
12321232
// variant(x, y, z)
1233-
let variant = self.tcx().lookup_adt_def(enum_def).variant_with_id(def_id);
1234-
let adjust = pat_adjust_pos(variant.fields.len(), subpats.len(), ddpos);
1235-
for (i, subpat) in subpats.iter().enumerate() {
1233+
let expected_len = self.tcx().lookup_adt_def(enum_def)
1234+
.variant_with_id(def_id).fields.len();
1235+
for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
12361236
let subpat_ty = self.pat_ty(&subpat)?; // see (*2)
12371237

12381238
let subcmt =
12391239
self.cat_imm_interior(
12401240
pat, cmt.clone(), subpat_ty,
1241-
InteriorField(PositionalField(adjust(i))));
1241+
InteriorField(PositionalField(i)));
12421242

12431243
self.cat_pattern_(subcmt, &subpat, op)?;
12441244
}
@@ -1253,13 +1253,12 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
12531253
}
12541254
};
12551255

1256-
let adjust = pat_adjust_pos(expected_len, subpats.len(), ddpos);
1257-
for (i, subpat) in subpats.iter().enumerate() {
1256+
for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
12581257
let subpat_ty = self.pat_ty(&subpat)?; // see (*2)
12591258
let cmt_field =
12601259
self.cat_imm_interior(
12611260
pat, cmt.clone(), subpat_ty,
1262-
InteriorField(PositionalField(adjust(i))));
1261+
InteriorField(PositionalField(i)));
12631262
self.cat_pattern_(cmt_field, &subpat, op)?;
12641263
}
12651264
}
@@ -1300,13 +1299,12 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
13001299
Ok(&ty::TyS{sty: ty::TyTuple(ref tys), ..}) => tys.len(),
13011300
ref ty => span_bug!(pat.span, "tuple pattern unexpected type {:?}", ty),
13021301
};
1303-
let adjust = pat_adjust_pos(expected_len, subpats.len(), ddpos);
1304-
for (i, subpat) in subpats.iter().enumerate() {
1302+
for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
13051303
let subpat_ty = self.pat_ty(&subpat)?; // see (*2)
13061304
let subcmt =
13071305
self.cat_imm_interior(
13081306
pat, cmt.clone(), subpat_ty,
1309-
InteriorField(PositionalField(adjust(i))));
1307+
InteriorField(PositionalField(i)));
13101308
self.cat_pattern_(subcmt, &subpat, op)?;
13111309
}
13121310
}

src/librustc/middle/stability.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use util::nodemap::{DefIdMap, FnvHashSet, FnvHashMap};
3333
use hir;
3434
use hir::{Item, Generics, StructField, Variant, PatKind};
3535
use hir::intravisit::{self, Visitor};
36-
use hir::pat_util::pat_adjust_pos;
36+
use hir::pat_util::EnumerateAndAdjustIterator;
3737

3838
use std::mem::replace;
3939
use std::cmp::Ordering;
@@ -616,9 +616,8 @@ pub fn check_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pat: &hir::Pat,
616616
match pat.node {
617617
// Foo(a, b, c)
618618
PatKind::TupleStruct(_, ref pat_fields, ddpos) => {
619-
let adjust = pat_adjust_pos(v.fields.len(), pat_fields.len(), ddpos);
620-
for (i, field) in pat_fields.iter().enumerate() {
621-
maybe_do_stability_check(tcx, v.fields[adjust(i)].did, field.span, cb)
619+
for (i, field) in pat_fields.iter().enumerate_and_adjust(v.fields.len(), ddpos) {
620+
maybe_do_stability_check(tcx, v.fields[i].did, field.span, cb)
622621
}
623622
}
624623
// Foo { a, b, c }

src/librustc_const_eval/check_match.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -924,7 +924,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
924924
Def::Variant(..) | Def::Struct(..) => {
925925
match ddpos {
926926
Some(ddpos) => {
927-
let mut pats = args[..ddpos].iter().map(|p| &**p).collect(): Vec<_>;
927+
let mut pats: Vec<_> = args[..ddpos].iter().map(|p| &**p).collect();
928928
pats.extend(repeat(DUMMY_WILD_PAT).take(arity - args.len()));
929929
pats.extend(args[ddpos..].iter().map(|p| &**p));
930930
Some(pats)
@@ -958,7 +958,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
958958
}
959959

960960
PatKind::Tuple(ref args, Some(ddpos)) => {
961-
let mut pats = args[..ddpos].iter().map(|p| &**p).collect(): Vec<_>;
961+
let mut pats: Vec<_> = args[..ddpos].iter().map(|p| &**p).collect();
962962
pats.extend(repeat(DUMMY_WILD_PAT).take(arity - args.len()));
963963
pats.extend(args[ddpos..].iter().map(|p| &**p));
964964
Some(pats)

src/librustc_const_eval/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
#![feature(question_mark)]
3232
#![feature(box_patterns)]
3333
#![feature(box_syntax)]
34-
#![feature(type_ascription)]
3534

3635
#[macro_use] extern crate syntax;
3736
#[macro_use] extern crate log;

src/librustc_mir/hair/cx/pattern.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use hair::cx::Cx;
1313
use rustc_data_structures::fnv::FnvHashMap;
1414
use rustc_const_eval as const_eval;
1515
use rustc::hir::def::Def;
16-
use rustc::hir::pat_util::{pat_adjust_pos, pat_is_resolved_const, pat_is_binding};
16+
use rustc::hir::pat_util::{EnumerateAndAdjustIterator, pat_is_resolved_const, pat_is_binding};
1717
use rustc::ty::{self, Ty};
1818
use rustc::mir::repr::*;
1919
use rustc::hir::{self, PatKind};
@@ -151,12 +151,11 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
151151
PatKind::Tuple(ref subpatterns, ddpos) => {
152152
match self.cx.tcx.node_id_to_type(pat.id).sty {
153153
ty::TyTuple(ref tys) => {
154-
let adjust = pat_adjust_pos(tys.len(), subpatterns.len(), ddpos);
155154
let subpatterns =
156155
subpatterns.iter()
157-
.enumerate()
156+
.enumerate_and_adjust(tys.len(), ddpos)
158157
.map(|(i, subpattern)| FieldPattern {
159-
field: Field::new(adjust(i)),
158+
field: Field::new(i),
160159
pattern: self.to_pattern(subpattern),
161160
})
162161
.collect();
@@ -224,12 +223,11 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
224223
let def = self.cx.tcx.def_map.borrow().get(&pat.id).unwrap().full_def();
225224
let variant_def = adt_def.variant_of_def(def);
226225

227-
let adjust = pat_adjust_pos(variant_def.fields.len(), subpatterns.len(), ddpos);
228226
let subpatterns =
229227
subpatterns.iter()
230-
.enumerate()
228+
.enumerate_and_adjust(variant_def.fields.len(), ddpos)
231229
.map(|(i, field)| FieldPattern {
232-
field: Field::new(adjust(i)),
230+
field: Field::new(i),
233231
pattern: self.to_pattern(field),
234232
})
235233
.collect();

src/librustc_privacy/lib.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use std::mem::replace;
3131

3232
use rustc::hir::{self, PatKind};
3333
use rustc::hir::intravisit::{self, Visitor};
34-
use rustc::hir::pat_util::pat_adjust_pos;
34+
use rustc::hir::pat_util::EnumerateAndAdjustIterator;
3535
use rustc::dep_graph::DepNode;
3636
use rustc::lint;
3737
use rustc::hir::def::{self, Def};
@@ -491,14 +491,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
491491
PatKind::TupleStruct(_, ref fields, ddpos) => {
492492
match self.tcx.pat_ty(pattern).sty {
493493
ty::TyStruct(def, _) => {
494-
let adjust = pat_adjust_pos(def.struct_variant().fields.len(),
495-
fields.len(), ddpos);
496-
for (i, field) in fields.iter().enumerate() {
494+
let expected_len = def.struct_variant().fields.len();
495+
for (i, field) in fields.iter().enumerate_and_adjust(expected_len, ddpos) {
497496
if let PatKind::Wild = field.node {
498497
continue
499498
}
500-
self.check_field(field.span, def,
501-
&def.struct_variant().fields[adjust(i)]);
499+
self.check_field(field.span, def, &def.struct_variant().fields[i]);
502500
}
503501
}
504502
ty::TyEnum(..) => {

src/librustc_trans/_match.rs

+7-10
Original file line numberDiff line numberDiff line change
@@ -1843,12 +1843,12 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
18431843
&repr,
18441844
Disr::from(vinfo.disr_val),
18451845
val);
1846-
let adjust = pat_adjust_pos(vinfo.fields.len(), sub_pats.len(), ddpos);
1847-
for (i, subpat) in sub_pats.iter().enumerate() {
1846+
for (i, subpat) in sub_pats.iter()
1847+
.enumerate_and_adjust(vinfo.fields.len(), ddpos) {
18481848
bcx = bind_irrefutable_pat(
18491849
bcx,
18501850
subpat,
1851-
MatchInput::from_val(args.vals[adjust(i)]),
1851+
MatchInput::from_val(args.vals[i]),
18521852
cleanup_scope);
18531853
}
18541854
}
@@ -1862,12 +1862,10 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
18621862
}
18631863
};
18641864

1865-
let adjust = pat_adjust_pos(expected_len, sub_pats.len(), ddpos);
18661865
let repr = adt::represent_node(bcx, pat.id);
18671866
let val = adt::MaybeSizedValue::sized(val.val);
1868-
for (i, elem) in sub_pats.iter().enumerate() {
1869-
let fldptr = adt::trans_field_ptr(bcx, &repr,
1870-
val, Disr(0), adjust(i));
1867+
for (i, elem) in sub_pats.iter().enumerate_and_adjust(expected_len, ddpos) {
1868+
let fldptr = adt::trans_field_ptr(bcx, &repr, val, Disr(0), i);
18711869
bcx = bind_irrefutable_pat(
18721870
bcx,
18731871
&elem,
@@ -1923,11 +1921,10 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
19231921
PatKind::Tuple(ref elems, ddpos) => {
19241922
match tcx.node_id_to_type(pat.id).sty {
19251923
ty::TyTuple(ref tys) => {
1926-
let adjust = pat_adjust_pos(tys.len(), elems.len(), ddpos);
19271924
let repr = adt::represent_node(bcx, pat.id);
19281925
let val = adt::MaybeSizedValue::sized(val.val);
1929-
for (i, elem) in elems.iter().enumerate() {
1930-
let fldptr = adt::trans_field_ptr(bcx, &repr, val, Disr(0), adjust(i));
1926+
for (i, elem) in elems.iter().enumerate_and_adjust(tys.len(), ddpos) {
1927+
let fldptr = adt::trans_field_ptr(bcx, &repr, val, Disr(0), i);
19311928
bcx = bind_irrefutable_pat(
19321929
bcx,
19331930
&elem,

src/librustc_typeck/check/_match.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use hir::def::{self, Def};
1212
use rustc::infer::{self, InferOk, TypeOrigin};
1313
use hir::pat_util::{PatIdMap, pat_id_map, pat_is_binding};
14-
use hir::pat_util::{pat_adjust_pos, pat_is_resolved_const};
14+
use hir::pat_util::{EnumerateAndAdjustIterator, pat_is_resolved_const};
1515
use rustc::ty::subst::Substs;
1616
use rustc::ty::{self, Ty, TypeFoldable, LvaluePreference};
1717
use check::{FnCtxt, Expectation};
@@ -271,13 +271,12 @@ impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, 'tcx> {
271271
}
272272
let max_len = cmp::max(expected_len, elements.len());
273273

274-
let element_tys = (0 .. max_len).map(|_| self.next_ty_var()).collect(): Vec<_>;
274+
let element_tys: Vec<_> = (0 .. max_len).map(|_| self.next_ty_var()).collect();
275275
let pat_ty = tcx.mk_tup(element_tys.clone());
276276
self.write_ty(pat.id, pat_ty);
277277
self.demand_eqtype(pat.span, expected, pat_ty);
278-
let adjust = pat_adjust_pos(expected_len, elements.len(), ddpos);
279-
for i in 0 .. elements.len() {
280-
self.check_pat(&elements[i], &element_tys[adjust(i)]);
278+
for (i, elem) in elements.iter().enumerate_and_adjust(expected_len, ddpos) {
279+
self.check_pat(elem, &element_tys[i]);
281280
}
282281
}
283282
PatKind::Box(ref inner) => {
@@ -734,12 +733,10 @@ impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, 'tcx> {
734733
_ => {}
735734
}
736735

737-
let adjust = pat_adjust_pos(variant.fields.len(), subpats.len(), ddpos);
738736
if subpats.len() == variant.fields.len() ||
739737
subpats.len() < variant.fields.len() && ddpos.is_some() {
740-
for (i, subpat) in subpats.iter().enumerate() {
741-
let field_ty = self.field_ty(subpat.span,
742-
&variant.fields[adjust(i)], expected_substs);
738+
for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) {
739+
let field_ty = self.field_ty(subpat.span, &variant.fields[i], expected_substs);
743740
self.check_pat(&subpat, field_ty);
744741
}
745742
} else {

src/librustc_typeck/lib.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,11 @@ This API is completely unstable and subject to change.
7777
#![feature(box_patterns)]
7878
#![feature(box_syntax)]
7979
#![feature(iter_arith)]
80-
#![feature(question_mark)]
8180
#![feature(quote)]
8281
#![feature(rustc_diagnostic_macros)]
8382
#![feature(rustc_private)]
8483
#![feature(staged_api)]
85-
#![feature(type_ascription)]
84+
#![feature(question_mark)]
8685

8786
#[macro_use] extern crate log;
8887
#[macro_use] extern crate syntax;

0 commit comments

Comments
 (0)