diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index 2abf499185690..c006452de3a7a 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -93,6 +93,7 @@ use syntax::ast; use syntax::codemap::{self, Pos, Span}; use syntax::parse::token; use syntax::ptr::P; +use syntax::util::MoveMap; impl<'tcx> ty::ctxt<'tcx> { pub fn note_and_explain_region(&self, @@ -1153,19 +1154,19 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { } fn rebuild_ty_params(&self, - ty_params: P<[hir::TyParam]>, + ty_params: hir::HirVec, lifetime: hir::Lifetime, region_names: &HashSet) - -> P<[hir::TyParam]> { - ty_params.map(|ty_param| { - let bounds = self.rebuild_ty_param_bounds(ty_param.bounds.clone(), + -> hir::HirVec { + ty_params.move_map(|ty_param| { + let bounds = self.rebuild_ty_param_bounds(ty_param.bounds, lifetime, region_names); hir::TyParam { name: ty_param.name, id: ty_param.id, bounds: bounds, - default: ty_param.default.clone(), + default: ty_param.default, span: ty_param.span, } }) @@ -1176,15 +1177,15 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { lifetime: hir::Lifetime, region_names: &HashSet) -> hir::TyParamBounds { - ty_param_bounds.map(|tpb| { + ty_param_bounds.move_map(|tpb| { match tpb { - &hir::RegionTyParamBound(lt) => { + hir::RegionTyParamBound(lt) => { // FIXME -- it's unclear whether I'm supposed to // substitute lifetime here. I suspect we need to // be passing down a map. hir::RegionTyParamBound(lt) } - &hir::TraitTyParamBound(ref poly_tr, modifier) => { + hir::TraitTyParamBound(ref poly_tr, modifier) => { let tr = &poly_tr.trait_ref; let last_seg = tr.path.segments.last().unwrap(); let mut insert = Vec::new(); @@ -1248,7 +1249,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { add: &Vec, keep: &HashSet, remove: &HashSet, - ty_params: P<[hir::TyParam]>, + ty_params: hir::HirVec, where_clause: hir::WhereClause) -> hir::Generics { let mut lifetimes = Vec::new(); @@ -1498,10 +1499,10 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { } } } - let new_types = data.types.map(|t| { + let new_types = data.types.iter().map(|t| { self.rebuild_arg_ty_or_output(&**t, lifetime, anon_nums, region_names) - }); - let new_bindings = data.bindings.map(|b| { + }).collect(); + let new_bindings = data.bindings.iter().map(|b| { hir::TypeBinding { id: b.id, name: b.name, @@ -1511,7 +1512,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { region_names), span: b.span } - }); + }).collect(); hir::AngleBracketedParameters(hir::AngleBracketedParameterData { lifetimes: new_lts.into(), types: new_types, diff --git a/src/librustc_front/fold.rs b/src/librustc_front/fold.rs index 784428cc114dc..75b6757867948 100644 --- a/src/librustc_front/fold.rs +++ b/src/librustc_front/fold.rs @@ -19,7 +19,7 @@ use hir; use syntax::codemap::{respan, Span, Spanned}; use syntax::ptr::P; use syntax::parse::token; -use syntax::util::move_map::MoveMap; +use syntax::util::{MoveMap, MoveFlatMap}; pub trait Folder : Sized { // Any additions to this trait should happen in form @@ -210,7 +210,7 @@ pub trait Folder : Sized { noop_fold_ty_param(tp, self) } - fn fold_ty_params(&mut self, tps: P<[TyParam]>) -> P<[TyParam]> { + fn fold_ty_params(&mut self, tps: HirVec) -> HirVec { noop_fold_ty_params(tps, self) } @@ -575,9 +575,9 @@ pub fn noop_fold_ty_param(tp: TyParam, fld: &mut T) -> TyParam { } } -pub fn noop_fold_ty_params(tps: P<[TyParam]>, +pub fn noop_fold_ty_params(tps: HirVec, fld: &mut T) - -> P<[TyParam]> { + -> HirVec { tps.move_map(|tp| fld.fold_ty_param(tp)) } diff --git a/src/librustc_front/hir.rs b/src/librustc_front/hir.rs index 6b2664af60ba5..45ccb5a2f8f72 100644 --- a/src/librustc_front/hir.rs +++ b/src/librustc_front/hir.rs @@ -208,8 +208,8 @@ impl PathParameters { pub fn none() -> PathParameters { AngleBracketedParameters(AngleBracketedParameterData { lifetimes: HirVec::new(), - types: P::empty(), - bindings: P::empty(), + types: HirVec::new(), + bindings: HirVec::new(), }) } @@ -282,10 +282,10 @@ pub struct AngleBracketedParameterData { /// The lifetime parameters for this path segment. pub lifetimes: HirVec, /// The type parameters for this path segment, if present. - pub types: P<[P]>, + pub types: HirVec>, /// Bindings (equality constraints) on associated types, if present. /// E.g., `Foo`. - pub bindings: P<[TypeBinding]>, + pub bindings: HirVec, } impl AngleBracketedParameterData { @@ -325,7 +325,7 @@ pub enum TraitBoundModifier { Maybe, } -pub type TyParamBounds = P<[TyParamBound]>; +pub type TyParamBounds = HirVec; #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct TyParam { @@ -341,7 +341,7 @@ pub struct TyParam { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct Generics { pub lifetimes: HirVec, - pub ty_params: P<[TyParam]>, + pub ty_params: HirVec, pub where_clause: WhereClause, } diff --git a/src/librustc_front/lowering.rs b/src/librustc_front/lowering.rs index db30ee9a5d2d3..07fdbc7676a4a 100644 --- a/src/librustc_front/lowering.rs +++ b/src/librustc_front/lowering.rs @@ -433,8 +433,8 @@ pub fn lower_ty_param(lctx: &LoweringContext, tp: &TyParam) -> hir::TyParam { } pub fn lower_ty_params(lctx: &LoweringContext, - tps: &P<[TyParam]>) - -> P<[hir::TyParam]> { + tps: &[TyParam]) + -> hir::HirVec { tps.iter().map(|tp| lower_ty_param(lctx, tp)).collect() } @@ -1771,19 +1771,19 @@ fn path_ident(span: Span, id: hir::Ident) -> hir::Path { } fn path(span: Span, strs: Vec) -> hir::Path { - path_all(span, false, strs, hir::HirVec::new(), Vec::new(), Vec::new()) + path_all(span, false, strs, hir::HirVec::new(), hir::HirVec::new(), hir::HirVec::new()) } fn path_global(span: Span, strs: Vec) -> hir::Path { - path_all(span, true, strs, hir::HirVec::new(), Vec::new(), Vec::new()) + path_all(span, true, strs, hir::HirVec::new(), hir::HirVec::new(), hir::HirVec::new()) } fn path_all(sp: Span, global: bool, mut idents: Vec, lifetimes: hir::HirVec, - types: Vec>, - bindings: Vec) + types: hir::HirVec>, + bindings: hir::HirVec) -> hir::Path { let last_identifier = idents.pop().unwrap(); let mut segments: Vec = idents.into_iter() @@ -1798,8 +1798,8 @@ fn path_all(sp: Span, identifier: last_identifier, parameters: hir::AngleBracketedParameters(hir::AngleBracketedParameterData { lifetimes: lifetimes, - types: P::from_vec(types), - bindings: P::from_vec(bindings), + types: types.into(), + bindings: bindings.into(), }), }); hir::Path { diff --git a/src/librustc_front/print/pprust.rs b/src/librustc_front/print/pprust.rs index 9ac0e65cba33b..edfefeec3e3bd 100644 --- a/src/librustc_front/print/pprust.rs +++ b/src/librustc_front/print/pprust.rs @@ -518,7 +518,7 @@ impl<'a> State<'a> { hir::TyBareFn(ref f) => { let generics = hir::Generics { lifetimes: f.lifetimes.clone(), - ty_params: P::empty(), + ty_params: hir::HirVec::new(), where_clause: hir::WhereClause { id: ast::DUMMY_NODE_ID, predicates: hir::HirVec::new(), @@ -2257,7 +2257,7 @@ impl<'a> State<'a> { } let generics = hir::Generics { lifetimes: hir::HirVec::new(), - ty_params: P::empty(), + ty_params: hir::HirVec::new(), where_clause: hir::WhereClause { id: ast::DUMMY_NODE_ID, predicates: hir::HirVec::new(), diff --git a/src/librustc_front/util.rs b/src/librustc_front/util.rs index 298904d1e0d7a..57ffefd3be435 100644 --- a/src/librustc_front/util.rs +++ b/src/librustc_front/util.rs @@ -335,7 +335,7 @@ pub fn is_path(e: P) -> bool { pub fn empty_generics() -> Generics { Generics { lifetimes: HirVec::new(), - ty_params: P::empty(), + ty_params: HirVec::new(), where_clause: WhereClause { id: DUMMY_NODE_ID, predicates: HirVec::new(), @@ -353,8 +353,8 @@ pub fn ident_to_path(s: Span, ident: Ident) -> Path { identifier: ident, parameters: hir::AngleBracketedParameters(hir::AngleBracketedParameterData { lifetimes: HirVec::new(), - types: P::empty(), - bindings: P::empty(), + types: HirVec::new(), + bindings: HirVec::new(), }), }], } diff --git a/src/librustc_mir/hair/cx/to_ref.rs b/src/librustc_mir/hair/cx/to_ref.rs index da200a8a33f08..24fcc2f4fcd56 100644 --- a/src/librustc_mir/hair/cx/to_ref.rs +++ b/src/librustc_mir/hair/cx/to_ref.rs @@ -61,3 +61,13 @@ impl<'a,'tcx:'a,T,U> ToRef for &'tcx Vec self.iter().map(|expr| expr.to_ref()).collect() } } + +impl<'a,'tcx:'a,T,U> ToRef for &'tcx P<[T]> + where &'tcx T: ToRef +{ + type Output = Vec; + + fn to_ref(self) -> Vec { + self.iter().map(|expr| expr.to_ref()).collect() + } +} diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index bddf0e9ffb0cb..515a7706b8296 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4906,7 +4906,7 @@ pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &hir::Block) -> bool { } pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, - tps: &P<[hir::TyParam]>, + tps: &[hir::TyParam], ty: Ty<'tcx>) { debug!("check_bounds_are_used(n_tps={}, ty={:?})", tps.len(), ty); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 4b0ec8578c12e..8965d0523f334 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -260,8 +260,8 @@ impl PathParameters { pub fn none() -> PathParameters { AngleBracketedParameters(AngleBracketedParameterData { lifetimes: Vec::new(), - types: P::empty(), - bindings: P::empty(), + types: P::new(), + bindings: P::new(), }) } @@ -429,7 +429,7 @@ impl Default for Generics { fn default() -> Generics { Generics { lifetimes: Vec::new(), - ty_params: P::empty(), + ty_params: P::new(), where_clause: WhereClause { id: DUMMY_NODE_ID, predicates: Vec::new(), diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index d38b771814c28..e5a326eb033c5 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -42,8 +42,8 @@ pub fn ident_to_path(s: Span, identifier: Ident) -> Path { identifier: identifier, parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData { lifetimes: Vec::new(), - types: P::empty(), - bindings: P::empty(), + types: P::new(), + bindings: P::new(), }) } ), diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 46a39b98058a2..186245948beef 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -69,8 +69,8 @@ pub trait AstBuilder { fn ty_option(&self, ty: P) -> P; fn ty_infer(&self, sp: Span) -> P; - fn ty_vars(&self, ty_params: &P<[ast::TyParam]>) -> Vec> ; - fn ty_vars_global(&self, ty_params: &P<[ast::TyParam]>) -> Vec> ; + fn ty_vars(&self, ty_params: &[ast::TyParam]) -> Vec> ; + fn ty_vars_global(&self, ty_params: &[ast::TyParam]) -> Vec> ; fn typaram(&self, span: Span, @@ -330,8 +330,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> { identifier: last_identifier, parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData { lifetimes: lifetimes, - types: P::from_vec(types), - bindings: P::from_vec(bindings), + types: P::from(types), + bindings: P::from(bindings), }) }); ast::Path { @@ -368,8 +368,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> { identifier: ident, parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData { lifetimes: lifetimes, - types: P::from_vec(types), - bindings: P::from_vec(bindings), + types: P::from(types), + bindings: P::from(bindings), }) }); @@ -461,11 +461,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> { // these are strange, and probably shouldn't be used outside of // pipes. Specifically, the global version possible generates // incorrect code. - fn ty_vars(&self, ty_params: &P<[ast::TyParam]>) -> Vec> { + fn ty_vars(&self, ty_params: &[ast::TyParam]) -> Vec> { ty_params.iter().map(|p| self.ty_ident(DUMMY_SP, p.ident)).collect() } - fn ty_vars_global(&self, ty_params: &P<[ast::TyParam]>) -> Vec> { + fn ty_vars_global(&self, ty_params: &[ast::TyParam]) -> Vec> { ty_params .iter() .map(|p| self.ty_path(self.path_global(DUMMY_SP, vec!(p.ident)))) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 743bcda18def4..2f36cdcdafc4b 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -24,7 +24,6 @@ use ext::base::*; use feature_gate::{self, Features}; use fold; use fold::*; -use util::move_map::MoveMap; use parse; use parse::token::{fresh_mark, fresh_name, intern}; use ptr::P; @@ -32,6 +31,7 @@ use util::small_vector::SmallVector; use visit; use visit::Visitor; use std_inject; +use util::MoveMap; use std::collections::HashSet; diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index cd2210c71b895..b60ffec287538 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -25,8 +25,8 @@ use ast_util; use codemap::{respan, Span, Spanned}; use parse::token; use ptr::P; +use util::{MoveMap, MoveFlatMap}; use util::small_vector::SmallVector; -use util::move_map::MoveMap; use std::rc::Rc; diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 47340d312242b..1774c784193a4 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -61,14 +61,16 @@ macro_rules! panictry { } pub mod util { + pub use self::move_map::{MoveMap, MoveFlatMap}; + pub mod interner; pub mod lev_distance; + pub mod move_map; pub mod node_count; pub mod parser; #[cfg(test)] pub mod parser_testing; pub mod small_vector; - pub mod move_map; } pub mod diagnostics { diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index cff106f838af2..85efa96bd834d 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -946,7 +946,7 @@ mod tests { abi::Rust, ast::Generics{ // no idea on either of these: lifetimes: Vec::new(), - ty_params: P::empty(), + ty_params: P::new(), where_clause: ast::WhereClause { id: ast::DUMMY_NODE_ID, predicates: Vec::new(), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ebfcf8c5180cf..cac0d997a6fe3 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -771,7 +771,7 @@ impl<'a> Parser<'a> { if i % 2 == 0 { match try!(f(self)) { Some(result) => v.push(result), - None => return Ok((P::from_vec(v), true)) + None => return Ok((P::from(v), true)) } } else { if let Some(t) = sep.as_ref() { @@ -780,7 +780,7 @@ impl<'a> Parser<'a> { } } - return Ok((P::from_vec(v), false)); + return Ok((P::from(v), false)); } /// Parse a sequence bracketed by '<' and '>', stopping @@ -1075,11 +1075,11 @@ impl<'a> Parser<'a> { let other_bounds = if try!(self.eat(&token::BinOp(token::Plus)) ){ try!(self.parse_ty_param_bounds(BoundParsingMode::Bare)) } else { - P::empty() + P::new() }; let all_bounds = Some(TraitTyParamBound(poly_trait_ref, TraitBoundModifier::None)).into_iter() - .chain(other_bounds.into_vec()) + .chain(other_bounds.into_iter()) .collect(); Ok(ast::TyPolyTraitRef(all_bounds)) } @@ -1708,8 +1708,8 @@ impl<'a> Parser<'a> { ast::AngleBracketedParameters(ast::AngleBracketedParameterData { lifetimes: lifetimes, - types: P::from_vec(types), - bindings: P::from_vec(bindings), + types: P::from(types), + bindings: P::from(bindings), }) } else if try!(self.eat(&token::OpenDelim(token::Paren)) ){ let lo = self.last_span.lo; @@ -1772,8 +1772,8 @@ impl<'a> Parser<'a> { identifier: identifier, parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData { lifetimes: lifetimes, - types: P::from_vec(types), - bindings: P::from_vec(bindings), + types: P::from(types), + bindings: P::from(bindings), }), }); @@ -3884,7 +3884,7 @@ impl<'a> Parser<'a> { -> PResult { if !try!(self.eat(&token::Colon) ){ - Ok(P::empty()) + Ok(P::new()) } else { self.parse_ty_param_bounds(mode) } @@ -3938,7 +3938,7 @@ impl<'a> Parser<'a> { } } - return Ok(P::from_vec(result)); + return Ok(P::from(result)); } /// Matches typaram = IDENT (`?` unbound)? optbounds ( EQ ty )? @@ -4051,7 +4051,7 @@ impl<'a> Parser<'a> { // If we found the `>`, don't continue. if !returned { - return Ok((lifetimes, types.into_vec(), Vec::new())); + return Ok((lifetimes, types.into(), Vec::new())); } // Then parse type bindings. @@ -4076,7 +4076,7 @@ impl<'a> Parser<'a> { })); } )); - Ok((lifetimes, types.into_vec(), bindings.into_vec())) + Ok((lifetimes, types.into(), bindings.into())) } fn forbid_lifetime(&mut self) -> PResult<()> { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 1f296dc5d59bd..4dc97b163fcd5 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1000,7 +1000,7 @@ impl<'a> State<'a> { ast::TyBareFn(ref f) => { let generics = ast::Generics { lifetimes: f.lifetimes.clone(), - ty_params: P::empty(), + ty_params: P::new(), where_clause: ast::WhereClause { id: ast::DUMMY_NODE_ID, predicates: Vec::new(), @@ -3023,7 +3023,7 @@ impl<'a> State<'a> { } let generics = ast::Generics { lifetimes: Vec::new(), - ty_params: P::empty(), + ty_params: P::new(), where_clause: ast::WhereClause { id: ast::DUMMY_NODE_ID, predicates: Vec::new(), diff --git a/src/libsyntax/ptr.rs b/src/libsyntax/ptr.rs index 1be0b08086d9c..e30d7bcc33d85 100644 --- a/src/libsyntax/ptr.rs +++ b/src/libsyntax/ptr.rs @@ -36,19 +36,40 @@ //! implementation changes (using a special thread-local heap, for example). //! Moreover, a switch to, e.g. `P<'a, T>` would be easy and mostly automated. -use std::fmt::{self, Display, Debug}; +use std::fmt; use std::iter::FromIterator; use std::ops::Deref; -use std::{ptr, slice, vec}; - +use std::ptr; +use std::slice; +use std::vec; use serialize::{Encodable, Decodable, Encoder, Decoder}; /// An owned smart pointer. -#[derive(Hash, PartialEq, Eq, PartialOrd, Ord)] +#[derive(PartialEq, Eq, Hash)] pub struct P { ptr: Box } +// ---------------------------------------------------------------------------- +// Common impls + +impl Deref for P { + type Target = T; + + fn deref(&self) -> &T { + &self.ptr + } +} + +impl fmt::Debug for P { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(&self.ptr, fmt) + } +} + +// ---------------------------------------------------------------------------- +// Impls for one boxed element `P` + #[allow(non_snake_case)] /// Construct a `P` from a `T` value. pub fn P(value: T) -> P { @@ -79,28 +100,15 @@ impl P { } } -impl Deref for P { - type Target = T; - - fn deref<'a>(&'a self) -> &'a T { - &*self.ptr - } -} - impl Clone for P { fn clone(&self) -> P { P((**self).clone()) } } -impl Debug for P { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - Debug::fmt(&**self, f) - } -} -impl Display for P { +impl fmt::Display for P { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - Display::fmt(&**self, f) + fmt::Display::fmt(&**self, f) } } @@ -122,64 +130,81 @@ impl Encodable for P { } } +// ---------------------------------------------------------------------------- +// Impls for boxed array `P<[T]>` (ex-`OwnedSlice`) -impl fmt::Debug for P<[T]> { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - self.ptr.fmt(fmt) +impl P<[T]> { + pub fn new() -> Self { + P { ptr: Box::new([]) as Box<[T]> } } -} -impl P<[T]> { + #[unstable(feature = "rustc_private", issue = "0")] + #[rustc_deprecated(since = "1.6.0", reason = "use `P::new` instead")] pub fn empty() -> P<[T]> { - P { ptr: Default::default() } + P { ptr: Box::new([]) as Box<[T]> } } - #[inline(never)] + #[unstable(feature = "rustc_private", issue = "0")] + #[rustc_deprecated(since = "1.6.0", reason = "use `P::from` instead")] pub fn from_vec(v: Vec) -> P<[T]> { P { ptr: v.into_boxed_slice() } } - #[inline(never)] + #[unstable(feature = "rustc_private", issue = "0")] + #[rustc_deprecated(since = "1.6.0", reason = "use `P::into` instead")] pub fn into_vec(self) -> Vec { self.ptr.into_vec() } + #[unstable(feature = "rustc_private", issue = "0")] + #[rustc_deprecated(since = "1.6.0", reason = "use `&owned_slice[..]` instead")] pub fn as_slice<'a>(&'a self) -> &'a [T] { &*self.ptr } + #[unstable(feature = "rustc_private", issue = "0")] + #[rustc_deprecated(since = "1.6.0", reason = "use `P::into_iter` instead")] pub fn move_iter(self) -> vec::IntoIter { - self.into_vec().into_iter() + self.ptr.into_vec().into_iter() } + #[unstable(feature = "rustc_private", issue = "0")] + #[rustc_deprecated(since = "1.6.0", reason = "use `iter().map(f).collect()` instead")] pub fn map U>(&self, f: F) -> P<[U]> { self.iter().map(f).collect() } } -impl Deref for P<[T]> { - type Target = [T]; - - fn deref(&self) -> &[T] { - self.as_slice() +impl Clone for P<[T]> { + fn clone(&self) -> Self { + P { ptr: self.ptr.clone() } } } -impl Default for P<[T]> { - fn default() -> P<[T]> { - P::empty() +impl From> for P<[T]> { + fn from(v: Vec) -> Self { + P { ptr: v.into_boxed_slice() } } } -impl Clone for P<[T]> { - fn clone(&self) -> P<[T]> { - P::from_vec(self.to_vec()) +impl Into> for P<[T]> { + fn into(self) -> Vec { + self.ptr.into_vec() } } impl FromIterator for P<[T]> { - fn from_iter>(iter: I) -> P<[T]> { - P::from_vec(iter.into_iter().collect()) + fn from_iter>(iter: I) -> Self { + P::from(iter.into_iter().collect::>()) + } +} + +impl IntoIterator for P<[T]> { + type Item = T; + type IntoIter = vec::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.ptr.into_vec().into_iter() } } @@ -187,21 +212,26 @@ impl<'a, T> IntoIterator for &'a P<[T]> { type Item = &'a T; type IntoIter = slice::Iter<'a, T>; fn into_iter(self) -> Self::IntoIter { - self.ptr.into_iter() + self.ptr.iter() + } +} + +impl<'a, T> IntoIterator for &'a mut P<[T]> { + type Item = &'a mut T; + type IntoIter = slice::IterMut<'a, T>; + fn into_iter(self) -> Self::IntoIter { + self.ptr.iter_mut() } } impl Encodable for P<[T]> { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - Encodable::encode(&**self, s) + fn encode(&self, s: &mut E) -> Result<(), E::Error> { + Encodable::encode(&self.ptr, s) } } impl Decodable for P<[T]> { - fn decode(d: &mut D) -> Result, D::Error> { - Ok(P::from_vec(match Decodable::decode(d) { - Ok(t) => t, - Err(e) => return Err(e) - })) + fn decode(d: &mut D) -> Result { + Ok(P { ptr: try!(Decodable::decode(d)) }) } } diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 9a6d1f8fdab4d..20c6f5b4be05e 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -30,7 +30,6 @@ use ext::base::ExtCtxt; use ext::build::AstBuilder; use ext::expand::ExpansionConfig; use fold::Folder; -use util::move_map::MoveMap; use fold; use parse::token::{intern, InternedString}; use parse::{token, ParseSess}; diff --git a/src/libsyntax/util/move_map.rs b/src/libsyntax/util/move_map.rs index e1078b719bf06..358ea7ac9b675 100644 --- a/src/libsyntax/util/move_map.rs +++ b/src/libsyntax/util/move_map.rs @@ -10,17 +10,36 @@ use std::ptr; -pub trait MoveMap: Sized { - fn move_map(self, mut f: F) -> Self where F: FnMut(T) -> T { - self.move_flat_map(|e| Some(f(e))) - } +pub trait MoveMap { + type Item; + fn move_map(self, f: F) -> Self + where F: FnMut(Self::Item) -> Self::Item; +} +pub trait MoveFlatMap { + type Item; fn move_flat_map(self, f: F) -> Self - where F: FnMut(T) -> I, - I: IntoIterator; + where F: FnMut(Self::Item) -> I, + I: IntoIterator; +} + +impl MoveMap for Container + where for<'a> &'a mut Container: IntoIterator +{ + type Item = T; + fn move_map(mut self, mut f: F) -> Container where F: FnMut(T) -> T { + for p in &mut self { + unsafe { + // FIXME(#5016) this shouldn't need to zero to be safe. + ptr::write(p, f(ptr::read_and_drop(p))); + } + } + self + } } -impl MoveMap for Vec { +impl MoveFlatMap for Vec { + type Item = T; fn move_flat_map(mut self, mut f: F) -> Self where F: FnMut(T) -> I, I: IntoIterator @@ -67,11 +86,13 @@ impl MoveMap for Vec { } } -impl MoveMap for ::ptr::P<[T]> { +impl MoveFlatMap for ::ptr::P<[T]> { + type Item = T; fn move_flat_map(self, f: F) -> Self where F: FnMut(T) -> I, I: IntoIterator { - ::ptr::P::from_vec(self.into_vec().move_flat_map(f)) + let v: Vec<_> = self.into(); + v.move_flat_map(f).into() } } diff --git a/src/libsyntax/util/small_vector.rs b/src/libsyntax/util/small_vector.rs index 8b07b21c578c9..5273572f46843 100644 --- a/src/libsyntax/util/small_vector.rs +++ b/src/libsyntax/util/small_vector.rs @@ -16,8 +16,6 @@ use std::mem; use std::slice; use std::vec; -use util::move_map::MoveMap; - /// A vector type optimized for cases where the size is almost always 0 or 1 pub struct SmallVector { repr: SmallVectorRepr, @@ -37,6 +35,14 @@ impl FromIterator for SmallVector { } } +impl<'a, T> IntoIterator for &'a mut SmallVector { + type Item = &'a mut T; + type IntoIter = slice::IterMut<'a, T>; + fn into_iter(self) -> Self::IntoIter { + self.as_slice_mut().iter_mut() + } +} + impl Extend for SmallVector { fn extend>(&mut self, iter: I) { for val in iter { @@ -71,6 +77,18 @@ impl SmallVector { } } + pub fn as_slice_mut(&mut self) -> &mut [T] { + match self.repr { + Zero => { + &mut [] + } + One(ref mut v) => { + unsafe { slice::from_raw_parts_mut(v, 1) } + } + Many(ref mut vs) => vs + } + } + pub fn pop(&mut self) -> Option { match self.repr { Zero => None, @@ -188,19 +206,6 @@ impl Iterator for IntoIter { } } -impl MoveMap for SmallVector { - fn move_flat_map(self, mut f: F) -> Self - where F: FnMut(T) -> I, - I: IntoIterator - { - match self.repr { - Zero => Self::zero(), - One(v) => f(v).into_iter().collect(), - Many(vs) => SmallVector { repr: Many(vs.move_flat_map(f)) }, - } - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index 8f316649421a6..6e4d523e15efc 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -489,7 +489,7 @@ impl<'a> TraitDef<'a> { let Generics { mut lifetimes, ty_params, mut where_clause } = self.generics.to_generics(cx, self.span, type_ident, generics); - let mut ty_params = ty_params.into_vec(); + let mut ty_params: Vec<_> = ty_params.into(); // Copy the lifetimes lifetimes.extend(generics.lifetimes.iter().cloned()); @@ -515,7 +515,7 @@ impl<'a> TraitDef<'a> { cx.typaram(self.span, ty_param.ident, - P::from_vec(bounds), + P::from(bounds), None) })); @@ -527,7 +527,7 @@ impl<'a> TraitDef<'a> { span: self.span, bound_lifetimes: wb.bound_lifetimes.clone(), bounded_ty: wb.bounded_ty.clone(), - bounds: P::from_vec(wb.bounds.iter().cloned().collect()) + bounds: wb.bounds.iter().cloned().collect() }) } ast::WherePredicate::RegionPredicate(ref rb) => { @@ -578,7 +578,7 @@ impl<'a> TraitDef<'a> { span: self.span, bound_lifetimes: vec![], bounded_ty: ty, - bounds: P::from_vec(bounds), + bounds: P::from(bounds), }; let predicate = ast::WherePredicate::BoundPredicate(predicate); @@ -589,7 +589,7 @@ impl<'a> TraitDef<'a> { let trait_generics = Generics { lifetimes: lifetimes, - ty_params: P::from_vec(ty_params), + ty_params: P::from(ty_params), where_clause: where_clause }; @@ -597,9 +597,9 @@ impl<'a> TraitDef<'a> { let trait_ref = cx.trait_ref(trait_path); // Create the type parameters on the `self` path. - let self_ty_params = generics.ty_params.map(|ty_param| { + let self_ty_params = generics.ty_params.iter().map(|ty_param| { cx.ty_ident(self.span, ty_param.ident) - }); + }).collect(); let self_lifetimes: Vec = generics.lifetimes @@ -610,7 +610,7 @@ impl<'a> TraitDef<'a> { // Create the type of `self`. let self_type = cx.ty_path( cx.path_all(self.span, false, vec!( type_ident ), self_lifetimes, - self_ty_params.into_vec(), Vec::new())); + self_ty_params, Vec::new())); let attr = cx.attribute( self.span, diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs index 10564b5f6985b..f3e0b8d8d16c6 100644 --- a/src/libsyntax_ext/deriving/generic/ty.rs +++ b/src/libsyntax_ext/deriving/generic/ty.rs @@ -169,15 +169,15 @@ impl<'a> Ty<'a> { -> ast::Path { match *self { Self_ => { - let self_params = self_generics.ty_params.map(|ty_param| { + let self_params = self_generics.ty_params.iter().map(|ty_param| { cx.ty_ident(span, ty_param.ident) - }); + }).collect(); let lifetimes = self_generics.lifetimes.iter() .map(|d| d.lifetime) .collect(); cx.path_all(span, false, vec!(self_ty), lifetimes, - self_params.into_vec(), Vec::new()) + self_params, Vec::new()) } Literal(ref p) => { p.to_path(cx, span, self_ty, self_generics) @@ -208,7 +208,7 @@ fn mk_generics(lifetimes: Vec, ty_params: Vec) -> Generics { Generics { lifetimes: lifetimes, - ty_params: P::from_vec(ty_params), + ty_params: P::from(ty_params), where_clause: ast::WhereClause { id: ast::DUMMY_NODE_ID, predicates: Vec::new(),