From 35ef09c38b3887a1880ad80874868afb41d28dd3 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 6 Mar 2016 15:54:44 +0300 Subject: [PATCH] Replace pat_adjust_pos with an iterator adapter --- src/librustc/hir/pat_util.rs | 36 +++++++++++++++-------- src/librustc/lib.rs | 2 -- src/librustc/middle/mem_categorization.rs | 20 ++++++------- src/librustc/middle/stability.rs | 7 ++--- src/librustc_const_eval/check_match.rs | 4 +-- src/librustc_const_eval/lib.rs | 1 - src/librustc_mir/hair/cx/pattern.rs | 12 ++++---- src/librustc_privacy/lib.rs | 10 +++---- src/librustc_trans/_match.rs | 17 +++++------ src/librustc_typeck/check/_match.rs | 15 ++++------ src/librustc_typeck/lib.rs | 3 +- 11 files changed, 61 insertions(+), 66 deletions(-) diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs index cf4842a25d6e..1008ba7a6e6a 100644 --- a/src/librustc/hir/pat_util.rs +++ b/src/librustc/hir/pat_util.rs @@ -18,28 +18,40 @@ use hir::{self, PatKind}; use syntax::codemap::{respan, Span, Spanned, DUMMY_SP}; use std::cell::RefCell; +use std::iter::{Enumerate, ExactSizeIterator}; pub type PatIdMap = FnvHashMap; -#[derive(Clone, Copy)] -pub struct AdjustPos { +pub struct EnumerateAndAdjust { + enumerate: Enumerate, gap_pos: usize, gap_len: usize, } -impl FnOnce<(usize,)> for AdjustPos { - type Output = usize; - extern "rust-call" fn call_once(self, (i,): (usize,)) -> usize { - if i < self.gap_pos { i } else { i + self.gap_len } +impl Iterator for EnumerateAndAdjust where I: Iterator { + type Item = (usize, ::Item); + + fn next(&mut self) -> Option<(usize, ::Item)> { + self.enumerate.next().map(|(i, elem)| { + (if i < self.gap_pos { i } else { i + self.gap_len }, elem) + }) } } -// Returns a functional object used to adjust tuple pattern indexes. Example: for 5-tuple and -// pattern (a, b, .., c) expected_len is 5, actual_len is 3 and gap_pos is Some(2). -pub fn pat_adjust_pos(expected_len: usize, actual_len: usize, gap_pos: Option) -> AdjustPos { - AdjustPos { - gap_pos: if let Some(gap_pos) = gap_pos { gap_pos } else { expected_len }, - gap_len: expected_len - actual_len, +pub trait EnumerateAndAdjustIterator { + fn enumerate_and_adjust(self, expected_len: usize, gap_pos: Option) + -> EnumerateAndAdjust where Self: Sized; +} + +impl EnumerateAndAdjustIterator for T { + fn enumerate_and_adjust(self, expected_len: usize, gap_pos: Option) + -> EnumerateAndAdjust where Self: Sized { + let actual_len = self.len(); + EnumerateAndAdjust { + enumerate: self.enumerate(), + gap_pos: if let Some(gap_pos) = gap_pos { gap_pos } else { expected_len }, + gap_len: expected_len - actual_len, + } } } diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 4ecad7f93a5a..e1fb701e641b 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -29,7 +29,6 @@ #![feature(collections)] #![feature(const_fn)] #![feature(enumset)] -#![feature(fn_traits)] #![feature(iter_arith)] #![feature(libc)] #![feature(nonzero)] @@ -39,7 +38,6 @@ #![feature(slice_patterns)] #![feature(staged_api)] #![feature(question_mark)] -#![feature(unboxed_closures)] #![cfg_attr(test, feature(test))] extern crate arena; diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index da3df7ad3e9a..e933b22f6079 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -80,7 +80,7 @@ use ty::adjustment; use ty::{self, Ty, TyCtxt}; use hir::{MutImmutable, MutMutable, PatKind}; -use hir::pat_util::pat_adjust_pos; +use hir::pat_util::EnumerateAndAdjustIterator; use hir; use syntax::ast; use syntax::codemap::Span; @@ -1230,15 +1230,15 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { match opt_def { Some(Def::Variant(enum_def, def_id)) => { // variant(x, y, z) - let variant = self.tcx().lookup_adt_def(enum_def).variant_with_id(def_id); - let adjust = pat_adjust_pos(variant.fields.len(), subpats.len(), ddpos); - for (i, subpat) in subpats.iter().enumerate() { + let expected_len = self.tcx().lookup_adt_def(enum_def) + .variant_with_id(def_id).fields.len(); + for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) { let subpat_ty = self.pat_ty(&subpat)?; // see (*2) let subcmt = self.cat_imm_interior( pat, cmt.clone(), subpat_ty, - InteriorField(PositionalField(adjust(i)))); + InteriorField(PositionalField(i))); self.cat_pattern_(subcmt, &subpat, op)?; } @@ -1253,13 +1253,12 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { } }; - let adjust = pat_adjust_pos(expected_len, subpats.len(), ddpos); - for (i, subpat) in subpats.iter().enumerate() { + for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) { let subpat_ty = self.pat_ty(&subpat)?; // see (*2) let cmt_field = self.cat_imm_interior( pat, cmt.clone(), subpat_ty, - InteriorField(PositionalField(adjust(i)))); + InteriorField(PositionalField(i))); self.cat_pattern_(cmt_field, &subpat, op)?; } } @@ -1300,13 +1299,12 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { Ok(&ty::TyS{sty: ty::TyTuple(ref tys), ..}) => tys.len(), ref ty => span_bug!(pat.span, "tuple pattern unexpected type {:?}", ty), }; - let adjust = pat_adjust_pos(expected_len, subpats.len(), ddpos); - for (i, subpat) in subpats.iter().enumerate() { + for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) { let subpat_ty = self.pat_ty(&subpat)?; // see (*2) let subcmt = self.cat_imm_interior( pat, cmt.clone(), subpat_ty, - InteriorField(PositionalField(adjust(i)))); + InteriorField(PositionalField(i))); self.cat_pattern_(subcmt, &subpat, op)?; } } diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 50b6d661fa8b..fcb03aba6d12 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -33,7 +33,7 @@ use util::nodemap::{DefIdMap, FnvHashSet, FnvHashMap}; use hir; use hir::{Item, Generics, StructField, Variant, PatKind}; use hir::intravisit::{self, Visitor}; -use hir::pat_util::pat_adjust_pos; +use hir::pat_util::EnumerateAndAdjustIterator; use std::mem::replace; use std::cmp::Ordering; @@ -616,9 +616,8 @@ pub fn check_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pat: &hir::Pat, match pat.node { // Foo(a, b, c) PatKind::TupleStruct(_, ref pat_fields, ddpos) => { - let adjust = pat_adjust_pos(v.fields.len(), pat_fields.len(), ddpos); - for (i, field) in pat_fields.iter().enumerate() { - maybe_do_stability_check(tcx, v.fields[adjust(i)].did, field.span, cb) + for (i, field) in pat_fields.iter().enumerate_and_adjust(v.fields.len(), ddpos) { + maybe_do_stability_check(tcx, v.fields[i].did, field.span, cb) } } // Foo { a, b, c } diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index f98734f21add..16b61534ee9a 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -924,7 +924,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat], Def::Variant(..) | Def::Struct(..) => { match ddpos { Some(ddpos) => { - let mut pats = args[..ddpos].iter().map(|p| &**p).collect(): Vec<_>; + let mut pats: Vec<_> = args[..ddpos].iter().map(|p| &**p).collect(); pats.extend(repeat(DUMMY_WILD_PAT).take(arity - args.len())); pats.extend(args[ddpos..].iter().map(|p| &**p)); Some(pats) @@ -958,7 +958,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat], } PatKind::Tuple(ref args, Some(ddpos)) => { - let mut pats = args[..ddpos].iter().map(|p| &**p).collect(): Vec<_>; + let mut pats: Vec<_> = args[..ddpos].iter().map(|p| &**p).collect(); pats.extend(repeat(DUMMY_WILD_PAT).take(arity - args.len())); pats.extend(args[ddpos..].iter().map(|p| &**p)); Some(pats) diff --git a/src/librustc_const_eval/lib.rs b/src/librustc_const_eval/lib.rs index 2c796690df43..9ab6a437a5ab 100644 --- a/src/librustc_const_eval/lib.rs +++ b/src/librustc_const_eval/lib.rs @@ -31,7 +31,6 @@ #![feature(question_mark)] #![feature(box_patterns)] #![feature(box_syntax)] -#![feature(type_ascription)] #[macro_use] extern crate syntax; #[macro_use] extern crate log; diff --git a/src/librustc_mir/hair/cx/pattern.rs b/src/librustc_mir/hair/cx/pattern.rs index 494d8a5c0356..b9ba860e8d0a 100644 --- a/src/librustc_mir/hair/cx/pattern.rs +++ b/src/librustc_mir/hair/cx/pattern.rs @@ -13,7 +13,7 @@ use hair::cx::Cx; use rustc_data_structures::fnv::FnvHashMap; use rustc_const_eval as const_eval; use rustc::hir::def::Def; -use rustc::hir::pat_util::{pat_adjust_pos, pat_is_resolved_const, pat_is_binding}; +use rustc::hir::pat_util::{EnumerateAndAdjustIterator, pat_is_resolved_const, pat_is_binding}; use rustc::ty::{self, Ty}; use rustc::mir::repr::*; use rustc::hir::{self, PatKind}; @@ -151,12 +151,11 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> { PatKind::Tuple(ref subpatterns, ddpos) => { match self.cx.tcx.node_id_to_type(pat.id).sty { ty::TyTuple(ref tys) => { - let adjust = pat_adjust_pos(tys.len(), subpatterns.len(), ddpos); let subpatterns = subpatterns.iter() - .enumerate() + .enumerate_and_adjust(tys.len(), ddpos) .map(|(i, subpattern)| FieldPattern { - field: Field::new(adjust(i)), + field: Field::new(i), pattern: self.to_pattern(subpattern), }) .collect(); @@ -224,12 +223,11 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> { let def = self.cx.tcx.def_map.borrow().get(&pat.id).unwrap().full_def(); let variant_def = adt_def.variant_of_def(def); - let adjust = pat_adjust_pos(variant_def.fields.len(), subpatterns.len(), ddpos); let subpatterns = subpatterns.iter() - .enumerate() + .enumerate_and_adjust(variant_def.fields.len(), ddpos) .map(|(i, field)| FieldPattern { - field: Field::new(adjust(i)), + field: Field::new(i), pattern: self.to_pattern(field), }) .collect(); diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 953bcf457b80..c90d152e3c31 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -31,7 +31,7 @@ use std::mem::replace; use rustc::hir::{self, PatKind}; use rustc::hir::intravisit::{self, Visitor}; -use rustc::hir::pat_util::pat_adjust_pos; +use rustc::hir::pat_util::EnumerateAndAdjustIterator; use rustc::dep_graph::DepNode; use rustc::lint; use rustc::hir::def::{self, Def}; @@ -491,14 +491,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { PatKind::TupleStruct(_, ref fields, ddpos) => { match self.tcx.pat_ty(pattern).sty { ty::TyStruct(def, _) => { - let adjust = pat_adjust_pos(def.struct_variant().fields.len(), - fields.len(), ddpos); - for (i, field) in fields.iter().enumerate() { + let expected_len = def.struct_variant().fields.len(); + for (i, field) in fields.iter().enumerate_and_adjust(expected_len, ddpos) { if let PatKind::Wild = field.node { continue } - self.check_field(field.span, def, - &def.struct_variant().fields[adjust(i)]); + self.check_field(field.span, def, &def.struct_variant().fields[i]); } } ty::TyEnum(..) => { diff --git a/src/librustc_trans/_match.rs b/src/librustc_trans/_match.rs index 9b168301f732..4b22e410f4c2 100644 --- a/src/librustc_trans/_match.rs +++ b/src/librustc_trans/_match.rs @@ -1843,12 +1843,12 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, &repr, Disr::from(vinfo.disr_val), val); - let adjust = pat_adjust_pos(vinfo.fields.len(), sub_pats.len(), ddpos); - for (i, subpat) in sub_pats.iter().enumerate() { + for (i, subpat) in sub_pats.iter() + .enumerate_and_adjust(vinfo.fields.len(), ddpos) { bcx = bind_irrefutable_pat( bcx, subpat, - MatchInput::from_val(args.vals[adjust(i)]), + MatchInput::from_val(args.vals[i]), cleanup_scope); } } @@ -1862,12 +1862,10 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, } }; - let adjust = pat_adjust_pos(expected_len, sub_pats.len(), ddpos); let repr = adt::represent_node(bcx, pat.id); let val = adt::MaybeSizedValue::sized(val.val); - for (i, elem) in sub_pats.iter().enumerate() { - let fldptr = adt::trans_field_ptr(bcx, &repr, - val, Disr(0), adjust(i)); + for (i, elem) in sub_pats.iter().enumerate_and_adjust(expected_len, ddpos) { + let fldptr = adt::trans_field_ptr(bcx, &repr, val, Disr(0), i); bcx = bind_irrefutable_pat( bcx, &elem, @@ -1923,11 +1921,10 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, PatKind::Tuple(ref elems, ddpos) => { match tcx.node_id_to_type(pat.id).sty { ty::TyTuple(ref tys) => { - let adjust = pat_adjust_pos(tys.len(), elems.len(), ddpos); let repr = adt::represent_node(bcx, pat.id); let val = adt::MaybeSizedValue::sized(val.val); - for (i, elem) in elems.iter().enumerate() { - let fldptr = adt::trans_field_ptr(bcx, &repr, val, Disr(0), adjust(i)); + for (i, elem) in elems.iter().enumerate_and_adjust(tys.len(), ddpos) { + let fldptr = adt::trans_field_ptr(bcx, &repr, val, Disr(0), i); bcx = bind_irrefutable_pat( bcx, &elem, diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index ce4ac4e815c7..693703c7236e 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -11,7 +11,7 @@ use hir::def::{self, Def}; use rustc::infer::{self, InferOk, TypeOrigin}; use hir::pat_util::{PatIdMap, pat_id_map, pat_is_binding}; -use hir::pat_util::{pat_adjust_pos, pat_is_resolved_const}; +use hir::pat_util::{EnumerateAndAdjustIterator, pat_is_resolved_const}; use rustc::ty::subst::Substs; use rustc::ty::{self, Ty, TypeFoldable, LvaluePreference}; use check::{FnCtxt, Expectation}; @@ -271,13 +271,12 @@ impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, 'tcx> { } let max_len = cmp::max(expected_len, elements.len()); - let element_tys = (0 .. max_len).map(|_| self.next_ty_var()).collect(): Vec<_>; + let element_tys: Vec<_> = (0 .. max_len).map(|_| self.next_ty_var()).collect(); let pat_ty = tcx.mk_tup(element_tys.clone()); self.write_ty(pat.id, pat_ty); self.demand_eqtype(pat.span, expected, pat_ty); - let adjust = pat_adjust_pos(expected_len, elements.len(), ddpos); - for i in 0 .. elements.len() { - self.check_pat(&elements[i], &element_tys[adjust(i)]); + for (i, elem) in elements.iter().enumerate_and_adjust(expected_len, ddpos) { + self.check_pat(elem, &element_tys[i]); } } PatKind::Box(ref inner) => { @@ -734,12 +733,10 @@ impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, 'tcx> { _ => {} } - let adjust = pat_adjust_pos(variant.fields.len(), subpats.len(), ddpos); if subpats.len() == variant.fields.len() || subpats.len() < variant.fields.len() && ddpos.is_some() { - for (i, subpat) in subpats.iter().enumerate() { - let field_ty = self.field_ty(subpat.span, - &variant.fields[adjust(i)], expected_substs); + for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) { + let field_ty = self.field_ty(subpat.span, &variant.fields[i], expected_substs); self.check_pat(&subpat, field_ty); } } else { diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 282b7582393e..0b23951db366 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -77,12 +77,11 @@ This API is completely unstable and subject to change. #![feature(box_patterns)] #![feature(box_syntax)] #![feature(iter_arith)] -#![feature(question_mark)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] #![feature(rustc_private)] #![feature(staged_api)] -#![feature(type_ascription)] +#![feature(question_mark)] #[macro_use] extern crate log; #[macro_use] extern crate syntax;