Replace pat_adjust_pos with an iterator adapter
This commit is contained in:
parent
c038b45423
commit
35ef09c38b
@ -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<ast::Name, ast::NodeId>;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct AdjustPos {
|
||||
pub struct EnumerateAndAdjust<I> {
|
||||
enumerate: Enumerate<I>,
|
||||
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<I> Iterator for EnumerateAndAdjust<I> where I: Iterator {
|
||||
type Item = (usize, <I as Iterator>::Item);
|
||||
|
||||
fn next(&mut self) -> Option<(usize, <I as Iterator>::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<usize>) -> 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<usize>)
|
||||
-> EnumerateAndAdjust<Self> where Self: Sized;
|
||||
}
|
||||
|
||||
impl<T: ExactSizeIterator> EnumerateAndAdjustIterator for T {
|
||||
fn enumerate_and_adjust(self, expected_len: usize, gap_pos: Option<usize>)
|
||||
-> EnumerateAndAdjust<Self> 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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)?;
|
||||
}
|
||||
}
|
||||
|
@ -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 }
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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(..) => {
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user