See http://static.rust-lang.org/doc/master/rustc/front/feature_gate/index.html for the problem this fixes.
implement `Eq` and `Hash`
* `collections::TrieMap` and `collections::TrieSet`, requiring the keys to be `uint`
* `collections::TreeMap` and `collections::TreeSet`, requiring the keys
- to implement `TotalOrd`
+ to implement `Ord`
These maps do not use managed pointers so they can be sent between tasks as
long as the key and value types are sendable. Neither the key or value type has
Supported traits for `deriving` are:
-* Comparison traits: `PartialEq`, `TotalEq`, `PartialOrd`, `TotalOrd`.
+* Comparison traits: `PartialEq`, `Eq`, `PartialOrd`, `Ord`.
* Serialization: `Encodable`, `Decodable`. These require `serialize`.
* `Clone`, to create `T` from `&T` via a copy.
* `Hash`, to iterate over the bytes in a data type.
}
~~~
-The full list of derivable traits is `PartialEq`, `TotalEq`, `Ord`,
-`TotalOrd`, `Encodable`, `Decodable`, `Clone`,
+The full list of derivable traits is `PartialEq`, `Eq`, `PartialOrd`,
+`Ord`, `Encodable`, `Decodable`, `Clone`,
`Hash`, `Rand`, `Default`, `Zero`, `FromPrimitive` and `Show`.
# Crates and the module system
('Clone', [], 1),
('PartialEq', [], 2),
('PartialOrd', ['PartialEq'], 8),
- ('TotalEq', ['PartialEq'], 1),
- ('TotalOrd', ['TotalEq', 'PartialOrd', 'PartialEq'], 1),
+ ('Eq', ['PartialEq'], 1),
+ ('Ord', ['Eq', 'PartialOrd', 'PartialEq'], 1),
('Show', [], 1),
('Hash', [], 1)]:
traits[trait] = (ALL, supers, errs)
syn keyword rustTrait ToCStr
syn keyword rustTrait Char
syn keyword rustTrait Clone
-syn keyword rustTrait Eq Ord TotalEq TotalOrd Ordering Equiv
+syn keyword rustTrait Eq Ord PartialEq PartialOrd Ordering Equiv
syn keyword rustEnumVariant Less Equal Greater
syn keyword rustTrait Container Mutable Map MutableMap Set MutableSet
syn keyword rustTrait FromIterator Extendable
syn keyword rustTrait Tuple9 Tuple10 Tuple11 Tuple12
syn keyword rustTrait CloneableVector ImmutableCloneableVector MutableCloneableVector
syn keyword rustTrait ImmutableVector MutableVector
-syn keyword rustTrait ImmutableEqVector ImmutableTotalOrdVector MutableTotalOrdVector
+syn keyword rustTrait ImmutableEqVector ImmutableOrdVector MutableOrdVector
syn keyword rustTrait Vector VectorVector OwnedVector MutableVectorAllocating
syn keyword rustTrait String
syn keyword rustTrait Vec
/// # use std::vec::Vec;
/// let vec: Vec<int> = Vec::with_capacity(10);
/// ```
+ #[inline]
pub fn with_capacity(capacity: uint) -> Vec<T> {
if mem::size_of::<T>() == 0 {
Vec { len: 0, cap: uint::MAX, ptr: 0 as *mut T }
/// let vec = Vec::from_fn(3, |idx| idx * 2);
/// assert_eq!(vec, vec!(0, 2, 4));
/// ```
+ #[inline]
pub fn from_fn(length: uint, op: |uint| -> T) -> Vec<T> {
unsafe {
let mut xs = Vec::with_capacity(length);
/// let slice = [1, 2, 3];
/// let vec = Vec::from_slice(slice);
/// ```
+ #[inline]
pub fn from_slice(values: &[T]) -> Vec<T> {
values.iter().map(|x| x.clone()).collect()
}
/// let vec = Vec::from_elem(3, "hi");
/// println!("{}", vec); // prints [hi, hi, hi]
/// ```
+ #[inline]
pub fn from_elem(length: uint, value: T) -> Vec<T> {
unsafe {
let mut xs = Vec::with_capacity(length);
}
impl<T> FromIterator<T> for Vec<T> {
+ #[inline]
fn from_iter<I:Iterator<T>>(mut iterator: I) -> Vec<T> {
let (lower, _) = iterator.size_hint();
let mut vector = Vec::with_capacity(lower);
}
impl<T> Extendable<T> for Vec<T> {
+ #[inline]
fn extend<I: Iterator<T>>(&mut self, mut iterator: I) {
let (lower, _) = iterator.size_hint();
self.reserve_additional(lower);
/// vec.push_all_move(vec!(box 2, box 3, box 4));
/// assert_eq!(vec, vec!(box 1, box 2, box 3, box 4));
/// ```
+ #[inline]
pub fn push_all_move(&mut self, other: Vec<T>) {
self.extend(other.move_iter());
}
/// let vec = vec!(1, 2, 3);
/// assert!(vec.contains(&1));
/// ```
+ #[inline]
pub fn contains(&self, x: &T) -> bool {
self.as_slice().contains(x)
}
#[cfg(test)]
mod tests {
+ extern crate test;
+
use std::prelude::*;
use std::mem::size_of;
+ use test::Bencher;
use super::{unzip, raw, Vec};
#[test]
let mut v = vec![BadElem(1), BadElem(2), BadElem(0xbadbeef), BadElem(4)];
v.truncate(0);
}
+
+ #[bench]
+ fn bench_new(b: &mut Bencher) {
+ b.iter(|| {
+ let v: Vec<int> = Vec::new();
+ assert_eq!(v.capacity(), 0);
+ assert!(v.as_slice() == []);
+ })
+ }
+
+ #[bench]
+ fn bench_with_capacity_0(b: &mut Bencher) {
+ b.iter(|| {
+ let v: Vec<int> = Vec::with_capacity(0);
+ assert_eq!(v.capacity(), 0);
+ assert!(v.as_slice() == []);
+ })
+ }
+
+
+ #[bench]
+ fn bench_with_capacity_5(b: &mut Bencher) {
+ b.iter(|| {
+ let v: Vec<int> = Vec::with_capacity(5);
+ assert_eq!(v.capacity(), 5);
+ assert!(v.as_slice() == []);
+ })
+ }
+
+ #[bench]
+ fn bench_with_capacity_100(b: &mut Bencher) {
+ b.iter(|| {
+ let v: Vec<int> = Vec::with_capacity(100);
+ assert_eq!(v.capacity(), 100);
+ assert!(v.as_slice() == []);
+ })
+ }
+
+ #[bench]
+ fn bench_from_fn_0(b: &mut Bencher) {
+ b.iter(|| {
+ let v: Vec<int> = Vec::from_fn(0, |_| 5);
+ assert!(v.as_slice() == []);
+ })
+ }
+
+ #[bench]
+ fn bench_from_fn_5(b: &mut Bencher) {
+ b.iter(|| {
+ let v: Vec<int> = Vec::from_fn(5, |_| 5);
+ assert!(v.as_slice() == [5, 5, 5, 5, 5]);
+ })
+ }
+
+ #[bench]
+ fn bench_from_slice_0(b: &mut Bencher) {
+ b.iter(|| {
+ let v: Vec<int> = Vec::from_slice([]);
+ assert!(v.as_slice() == []);
+ })
+ }
+
+ #[bench]
+ fn bench_from_slice_5(b: &mut Bencher) {
+ b.iter(|| {
+ let v: Vec<int> = Vec::from_slice([1, 2, 3, 4, 5]);
+ assert!(v.as_slice() == [1, 2, 3, 4, 5]);
+ })
+ }
+
+ #[bench]
+ fn bench_from_iter_0(b: &mut Bencher) {
+ b.iter(|| {
+ let v0: Vec<int> = vec!();
+ let v1: Vec<int> = FromIterator::from_iter(v0.move_iter());
+ assert!(v1.as_slice() == []);
+ })
+ }
+
+ #[bench]
+ fn bench_from_iter_5(b: &mut Bencher) {
+ b.iter(|| {
+ let v0: Vec<int> = vec!(1, 2, 3, 4, 5);
+ let v1: Vec<int> = FromIterator::from_iter(v0.move_iter());
+ assert!(v1.as_slice() == [1, 2, 3, 4, 5]);
+ })
+ }
+
+ #[bench]
+ fn bench_extend_0(b: &mut Bencher) {
+ b.iter(|| {
+ let v0: Vec<int> = vec!();
+ let mut v1: Vec<int> = vec!(1, 2, 3, 4, 5);
+ v1.extend(v0.move_iter());
+ assert!(v1.as_slice() == [1, 2, 3, 4, 5]);
+ })
+ }
+
+ #[bench]
+ fn bench_extend_5(b: &mut Bencher) {
+ b.iter(|| {
+ let v0: Vec<int> = vec!(1, 2, 3, 4, 5);
+ let mut v1: Vec<int> = vec!(1, 2, 3, 4, 5);
+ v1.extend(v0.move_iter());
+ assert!(v1.as_slice() == [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]);
+ })
+ }
}
pub fn get_type(tcx: &ty::ctxt,
def: ast::DefId)
- -> ty::ty_param_bounds_and_ty {
+ -> ty::Polytype {
let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate);
decoder::get_type(&*cdata, def.node, tcx)
}
pub fn get_field_type(tcx: &ty::ctxt, class_id: ast::DefId,
- def: ast::DefId) -> ty::ty_param_bounds_and_ty {
+ def: ast::DefId) -> ty::Polytype {
let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(class_id.krate);
let all_items = reader::get_doc(ebml::Doc::new(cdata.data()), tag_items);
def)).to_string()
});
let ty = decoder::item_type(def, the_field, tcx, &*cdata);
- ty::ty_param_bounds_and_ty {
+ ty::Polytype {
generics: ty::Generics {types: VecPerParamSpace::empty(),
regions: VecPerParamSpace::empty()},
ty: ty
}
pub fn get_type(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt)
- -> ty::ty_param_bounds_and_ty {
+ -> ty::Polytype {
let item = lookup_item(id, cdata.data());
let tp_defs = item_ty_param_defs(item, tcx, cdata, tag_items_data_item_ty_param_bounds);
let rp_defs = item_region_param_defs(item, cdata);
- ty::ty_param_bounds_and_ty {
+ ty::Polytype {
generics: ty::Generics {types: tp_defs,
regions: rp_defs},
ty: t
fn encode_bounds_and_type(ebml_w: &mut Encoder,
ecx: &EncodeContext,
- tpt: &ty::ty_param_bounds_and_ty) {
- encode_ty_type_param_defs(ebml_w, ecx, &tpt.generics.types,
+ pty: &ty::Polytype) {
+ encode_ty_type_param_defs(ebml_w, ecx, &pty.generics.types,
tag_items_data_item_ty_param_bounds);
- encode_region_param_defs(ebml_w, &tpt.generics.regions);
- encode_type(ecx, ebml_w, tpt.ty);
+ encode_region_param_defs(ebml_w, &pty.generics.regions);
+ encode_type(ecx, ebml_w, pty.ty);
}
fn encode_variant_id(ebml_w: &mut Encoder, vid: DefId) {
encode_stability(ebml_w, stab);
// The type for methods gets encoded twice, which is unfortunate.
- let tpt = lookup_item_type(ecx.tcx, m.def_id);
- encode_bounds_and_type(ebml_w, ecx, &tpt);
+ let pty = lookup_item_type(ecx.tcx, m.def_id);
+ encode_bounds_and_type(ebml_w, ecx, &pty);
let elem = ast_map::PathName(m.ident.name);
encode_path(ebml_w, impl_path.chain(Some(elem).move_iter()));
}
for &ast_method in ast_method_opt.iter() {
- let any_types = !tpt.generics.types.is_empty();
+ let any_types = !pty.generics.types.is_empty();
if any_types || is_default_impl || should_inline(ast_method.attrs.as_slice()) {
encode_inlined_item(ecx, ebml_w,
IIMethodRef(local_def(parent_id), false,
fn_style_static_method_family(
method_ty.fty.fn_style));
- let tpt = ty::lookup_item_type(tcx, method_def_id);
- encode_bounds_and_type(ebml_w, ecx, &tpt);
+ let pty = ty::lookup_item_type(tcx, method_def_id);
+ encode_bounds_and_type(ebml_w, ecx, &pty);
}
_ => {
// this.
if method_ty.explicit_self != SelfStatic {
// FIXME: I feel like there is something funny going on.
- let tpt = ty::lookup_item_type(tcx, method_def_id);
- encode_bounds_and_type(ebml_w, ecx, &tpt);
+ let pty = ty::lookup_item_type(tcx, method_def_id);
+ encode_bounds_and_type(ebml_w, ecx, &pty);
}
encode_method_sort(ebml_w, 'p');
encode_inlined_item(ecx, ebml_w,
fn emit_type_param_def(&mut self,
ecx: &e::EncodeContext,
type_param_def: &ty::TypeParameterDef);
- fn emit_tpbt(&mut self,
- ecx: &e::EncodeContext,
- tpbt: ty::ty_param_bounds_and_ty);
+ fn emit_polytype(&mut self,
+ ecx: &e::EncodeContext,
+ pty: ty::Polytype);
fn emit_substs(&mut self, ecx: &e::EncodeContext, substs: &subst::Substs);
fn emit_auto_adjustment(&mut self, ecx: &e::EncodeContext, adj: &ty::AutoAdjustment);
}
});
}
- fn emit_tpbt(&mut self,
+ fn emit_polytype(&mut self,
ecx: &e::EncodeContext,
- tpbt: ty::ty_param_bounds_and_ty) {
- self.emit_struct("ty_param_bounds_and_ty", 2, |this| {
+ pty: ty::Polytype) {
+ self.emit_struct("Polytype", 2, |this| {
this.emit_struct_field("generics", 0, |this| {
this.emit_struct("Generics", 2, |this| {
this.emit_struct_field("types", 0, |this| {
Ok(encode_vec_per_param_space(
- this, &tpbt.generics.types,
+ this, &pty.generics.types,
|this, def| this.emit_type_param_def(ecx, def)))
});
this.emit_struct_field("regions", 1, |this| {
Ok(encode_vec_per_param_space(
- this, &tpbt.generics.regions,
+ this, &pty.generics.regions,
|this, def| def.encode(this).unwrap()))
})
})
});
this.emit_struct_field("ty", 1, |this| {
- Ok(this.emit_ty(ecx, tpbt.ty))
+ Ok(this.emit_ty(ecx, pty.ty))
})
});
}
}
let lid = ast::DefId { krate: ast::LOCAL_CRATE, node: id };
- for &tpbt in tcx.tcache.borrow().find(&lid).iter() {
+ for &pty in tcx.tcache.borrow().find(&lid).iter() {
ebml_w.tag(c::tag_table_tcache, |ebml_w| {
ebml_w.id(id);
ebml_w.tag(c::tag_table_val, |ebml_w| {
- ebml_w.emit_tpbt(ecx, tpbt.clone());
+ ebml_w.emit_polytype(ecx, pty.clone());
})
})
}
fn read_tys(&mut self, xcx: &ExtendedDecodeContext) -> Vec<ty::t>;
fn read_type_param_def(&mut self, xcx: &ExtendedDecodeContext)
-> ty::TypeParameterDef;
- fn read_ty_param_bounds_and_ty(&mut self, xcx: &ExtendedDecodeContext)
- -> ty::ty_param_bounds_and_ty;
+ fn read_polytype(&mut self, xcx: &ExtendedDecodeContext)
+ -> ty::Polytype;
fn read_substs(&mut self, xcx: &ExtendedDecodeContext) -> subst::Substs;
fn read_auto_adjustment(&mut self, xcx: &ExtendedDecodeContext) -> ty::AutoAdjustment;
fn convert_def_id(&mut self,
}).unwrap()
}
- fn read_ty_param_bounds_and_ty(&mut self, xcx: &ExtendedDecodeContext)
- -> ty::ty_param_bounds_and_ty {
- self.read_struct("ty_param_bounds_and_ty", 2, |this| {
- Ok(ty::ty_param_bounds_and_ty {
+ fn read_polytype(&mut self, xcx: &ExtendedDecodeContext)
+ -> ty::Polytype {
+ self.read_struct("Polytype", 2, |this| {
+ Ok(ty::Polytype {
generics: this.read_struct_field("generics", 0, |this| {
this.read_struct("Generics", 2, |this| {
Ok(ty::Generics {
dcx.tcx.freevars.borrow_mut().insert(id, fv_info);
}
c::tag_table_tcache => {
- let tpbt = val_dsr.read_ty_param_bounds_and_ty(xcx);
+ let pty = val_dsr.read_polytype(xcx);
let lid = ast::DefId { krate: ast::LOCAL_CRATE, node: id };
- dcx.tcx.tcache.borrow_mut().insert(lid, tpbt);
+ dcx.tcx.tcache.borrow_mut().insert(lid, pty);
}
c::tag_table_param_defs => {
let bounds = val_dsr.read_type_param_def(xcx);
}
fn all_constructors(cx: &MatchCheckCtxt, m: &Matrix, left_ty: ty::t) -> Vec<ctor> {
+ // This produces a list of all vector constructors that we would expect to appear
+ // in an exhaustive set of patterns. Because such a list would normally be infinite,
+ // we narrow it down to only those constructors that actually appear in the inspected
+ // column, plus, any that are missing and not covered by a pattern with a destructured slice.
fn vec_constructors(m: &Matrix) -> Vec<ctor> {
let max_vec_len = m.iter().map(|r| match r.get(0).node {
PatVec(ref before, _, ref after) => before.len() + after.len(),
_ => 0u
}).max().unwrap_or(0u);
- let contains_slice = m.iter().any(|r| match r.get(0).node {
- PatVec(_, ref slice, _) => slice.is_some(),
- _ => false
- });
- let lengths = iter::range_inclusive(0u, if contains_slice {
- max_vec_len
- } else {
- max_vec_len + 1
- });
- lengths.map(|len| vec(len)).collect()
+ let min_vec_len_with_slice = m.iter().map(|r| match r.get(0).node {
+ PatVec(ref before, Some(_), ref after) => before.len() + after.len(),
+ _ => max_vec_len + 1
+ }).min().unwrap_or(max_vec_len + 1);
+ let other_lengths = m.iter().map(|r| match r.get(0).node {
+ PatVec(ref before, _, ref after) => before.len() + after.len(),
+ _ => 0u
+ }).filter(|&len| len > min_vec_len_with_slice);
+ iter::range_inclusive(0u, min_vec_len_with_slice)
+ .chain(other_lengths)
+ .map(|len| vec(len))
+ .collect()
}
match ty::get(left_ty).sty {
impl<'a> AstConv for Context<'a>{
fn tcx<'a>(&'a self) -> &'a ty::ctxt { self.tcx }
- fn get_item_ty(&self, id: ast::DefId) -> ty::ty_param_bounds_and_ty {
+ fn get_item_ty(&self, id: ast::DefId) -> ty::Polytype {
ty::lookup_item_type(self.tcx, id)
}
/// A polytype.
///
-/// - `bounds`: The list of bounds for each type parameter. The length of the
-/// list also tells you how many type parameters there are.
-///
-/// - `rp`: true if the type is region-parameterized. Types can have at
-/// most one region parameter, always called `&self`.
-///
-/// - `ty`: the base type. May have reference to the (unsubstituted) bound
-/// region `&self` or to (unsubstituted) ty_param types
+/// - `generics`: the set of type parameters and their bounds
+/// - `ty`: the base types, which may reference the parameters defined
+/// in `generics`
#[deriving(Clone)]
-pub struct ty_param_bounds_and_ty {
+pub struct Polytype {
pub generics: Generics,
pub ty: t
}
-/// As `ty_param_bounds_and_ty` but for a trait ref.
+/// As `Polytype` but for a trait ref.
pub struct TraitDef {
pub generics: Generics,
pub bounds: BuiltinBounds,
pub substs: Substs,
}
-pub struct ty_param_substs_and_ty {
- pub substs: Substs,
- pub ty: ty::t
-}
-
-pub type type_cache = RefCell<DefIdMap<ty_param_bounds_and_ty>>;
+pub type type_cache = RefCell<DefIdMap<Polytype>>;
pub type node_type_table = RefCell<HashMap<uint,t>>;
// the type cache. Returns the type parameters and type.
pub fn lookup_item_type(cx: &ctxt,
did: ast::DefId)
- -> ty_param_bounds_and_ty {
+ -> Polytype {
lookup_locally_or_in_crate_store(
"tcache", did, &mut *cx.tcache.borrow_mut(),
|| csearch::get_type(cx, did))
} else {
let mut tcache = tcx.tcache.borrow_mut();
match tcache.find(&id) {
- Some(&ty_param_bounds_and_ty {ty, ..}) => ty,
+ Some(&Polytype {ty, ..}) => ty,
None => {
let tpt = csearch::get_field_type(tcx, struct_id, id);
tcache.insert(id, tpt.clone());
use middle::def;
use middle::lang_items::FnMutTraitLangItem;
use rl = middle::resolve_lifetime;
-use middle::subst::{Subst, Substs};
-use middle::subst;
-use middle::ty::ty_param_substs_and_ty;
+use middle::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs};
use middle::ty;
+use middle::typeck::TypeAndSubsts;
use middle::typeck::lookup_def_tcx;
use middle::typeck::rscope::RegionScope;
use middle::typeck::rscope;
pub trait AstConv {
fn tcx<'a>(&'a self) -> &'a ty::ctxt;
- fn get_item_ty(&self, id: ast::DefId) -> ty::ty_param_bounds_and_ty;
+ fn get_item_ty(&self, id: ast::DefId) -> ty::Polytype;
fn get_trait_def(&self, id: ast::DefId) -> Rc<ty::TraitDef>;
// what type should we use when a type is omitted?
rscope: &RS,
decl_generics: &ty::Generics,
self_ty: Option<ty::t>,
- path: &ast::Path) -> subst::Substs
+ path: &ast::Path) -> Substs
{
/*!
* Given a path `path` that refers to an item `I` with the
// Note: in the case of traits, the self parameter is also
// defined, but we don't currently create a `type_param_def` for
// `Self` because it is implicit.
- assert!(decl_generics.regions.all(|d| d.space == subst::TypeSpace));
- assert!(decl_generics.types.all(|d| d.space != subst::FnSpace));
+ assert!(decl_generics.regions.all(|d| d.space == TypeSpace));
+ assert!(decl_generics.types.all(|d| d.space != FnSpace));
// If the type is parameterized by the this region, then replace this
// region with the current anon region binding (in other words,
// whatever & would get replaced with).
- let expected_num_region_params = decl_generics.regions.len(subst::TypeSpace);
+ let expected_num_region_params = decl_generics.regions.len(TypeSpace);
let supplied_num_region_params = path.segments.last().unwrap().lifetimes.len();
let regions = if expected_num_region_params == supplied_num_region_params {
path.segments.last().unwrap().lifetimes.iter().map(
};
// Convert the type parameters supplied by the user.
- let ty_param_defs = decl_generics.types.get_vec(subst::TypeSpace);
+ let ty_param_defs = decl_generics.types.get_vec(TypeSpace);
let supplied_ty_param_count = path.segments.iter().flat_map(|s| s.types.iter()).count();
let formal_ty_param_count = ty_param_defs.len();
let required_ty_param_count = ty_param_defs.iter()
.map(|a_t| ast_ty_to_ty(this, rscope, &**a_t))
.collect();
- let mut substs = subst::Substs::new_type(tps, regions);
+ let mut substs = Substs::new_type(tps, regions);
match self_ty {
None => {
// "declared" (in other words, this should be a
// trait-ref).
assert!(decl_generics.types.get_self().is_some());
- substs.types.push(subst::SelfSpace, ty);
+ substs.types.push(SelfSpace, ty);
}
}
for param in ty_param_defs.slice_from(supplied_ty_param_count).iter() {
let default = param.default.unwrap();
let default = default.subst_spanned(tcx, &substs, Some(path.span));
- substs.types.push(subst::TypeSpace, default);
+ substs.types.push(TypeSpace, default);
}
substs
rscope: &RS,
did: ast::DefId,
path: &ast::Path)
- -> ty_param_substs_and_ty
+ -> TypeAndSubsts
{
let tcx = this.tcx();
- let ty::ty_param_bounds_and_ty {
+ let ty::Polytype {
generics: generics,
ty: decl_ty
} = this.get_item_ty(did);
let substs = ast_path_substs(this, rscope, &generics, None, path);
let ty = decl_ty.subst(tcx, &substs);
- ty_param_substs_and_ty { substs: substs, ty: ty }
+ TypeAndSubsts { substs: substs, ty: ty }
}
pub static NO_REGIONS: uint = 1;
let output_type = ast_ty_to_ty(this,
rscope,
&*unboxed_function.decl.output);
- let mut substs = subst::Substs::new_type(vec!(input_tuple, output_type),
+ let mut substs = Substs::new_type(vec!(input_tuple, output_type),
Vec::new());
match self_ty {
- Some(s) => substs.types.push(subst::SelfSpace, s),
+ Some(s) => substs.types.push(SelfSpace, s),
None => ()
}
match v_def.variant_def_ids() {
Some((enm, var)) => {
// Assign the pattern the type of the *enum*, not the variant.
- let enum_tpt = ty::lookup_item_type(tcx, enm);
+ let enum_pty = ty::lookup_item_type(tcx, enm);
instantiate_path(pcx.fcx,
path,
- enum_tpt,
+ enum_pty,
v_def,
pat.span,
pat.id);
let s_def_id = s_def.def_id();
// Assign the pattern the type of the struct.
- let ctor_tpt = ty::lookup_item_type(tcx, s_def_id);
- let struct_tpt = if ty::is_fn_ty(ctor_tpt.ty) {
- ty::ty_param_bounds_and_ty {ty: ty::ty_fn_ret(ctor_tpt.ty),
- ..ctor_tpt}
+ let ctor_pty = ty::lookup_item_type(tcx, s_def_id);
+ let struct_pty = if ty::is_fn_ty(ctor_pty.ty) {
+ ty::Polytype {ty: ty::ty_fn_ret(ctor_pty.ty),
+ ..ctor_pty}
} else {
- ctor_tpt
+ ctor_pty
};
instantiate_path(pcx.fcx,
path,
- struct_tpt,
+ struct_pty,
s_def,
pat.span,
pat.id);
ast::PatEnum(..) |
ast::PatIdent(..) if pat_is_const(&tcx.def_map, pat) => {
let const_did = tcx.def_map.borrow().get_copy(&pat.id).def_id();
- let const_tpt = ty::lookup_item_type(tcx, const_did);
- demand::suptype(fcx, pat.span, expected, const_tpt.ty);
- fcx.write_ty(pat.id, const_tpt.ty);
+ let const_pty = ty::lookup_item_type(tcx, const_did);
+ demand::suptype(fcx, pat.span, expected, const_pty.ty);
+ fcx.write_ty(pat.id, const_pty.ty);
}
ast::PatIdent(bm, ref name, sub) if pat_is_binding(&tcx.def_map, pat) => {
let typ = fcx.local_ty(pat.span, pat.id);
use middle::typeck::{MethodStatic, MethodObject};
use middle::typeck::{param_index};
use middle::typeck::check::regionmanip::replace_late_bound_regions_in_fn_sig;
+use middle::typeck::TypeAndSubsts;
use util::common::indenter;
use util::ppaux;
use util::ppaux::Repr;
// variables for each parameter:
let span = self.self_expr.map_or(self.span, |e| e.span);
let vcx = self.fcx.vtable_context();
- let ty::ty_param_substs_and_ty {
+ let TypeAndSubsts {
substs: impl_substs,
ty: impl_ty
} = impl_self_ty(&vcx, span, impl_did);
use middle::subst;
use middle::subst::{Subst, Substs, VecPerParamSpace, ParamSpace};
use middle::ty::{FnSig, VariantInfo};
-use middle::ty::{ty_param_bounds_and_ty, ty_param_substs_and_ty};
+use middle::ty::{Polytype};
use middle::ty::{ParamTy, Disr, ExprTyProvider};
use middle::ty;
use middle::ty_fold::TypeFolder;
use middle::typeck::no_params;
use middle::typeck::{require_same_types, vtable_map};
use middle::typeck::{MethodCall, MethodMap};
+use middle::typeck::{TypeAndSubsts};
use middle::lang_items::TypeIdLangItem;
use util::common::{block_query, indenter, loop_query};
use util::ppaux;
it.id);
}
ast::ItemFn(ref decl, _, _, _, ref body) => {
- let fn_tpt = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id));
+ let fn_pty = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id));
let param_env = ty::construct_parameter_environment(ccx.tcx,
- &fn_tpt.generics,
+ &fn_pty.generics,
body.id);
- check_bare_fn(ccx, &**decl, &**body, it.id, fn_tpt.ty, param_env);
+ check_bare_fn(ccx, &**decl, &**body, it.id, fn_pty.ty, param_env);
}
ast::ItemImpl(_, ref opt_trait_ref, _, ref ms) => {
debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id);
- let impl_tpt = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id));
+ let impl_pty = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id));
for m in ms.iter() {
- check_method_body(ccx, &impl_tpt.generics, &**m);
+ check_method_body(ccx, &impl_pty.generics, &**m);
}
match *opt_trait_ref {
ast_trait_ref,
&*impl_trait_ref,
ms.as_slice());
- vtable::resolve_impl(ccx.tcx, it, &impl_tpt.generics, &*impl_trait_ref);
+ vtable::resolve_impl(ccx.tcx, it, &impl_pty.generics, &*impl_trait_ref);
}
None => { }
}
check_struct(ccx, it.id, it.span);
}
ast::ItemTy(ref t, ref generics) => {
- let tpt_ty = ty::node_id_to_type(ccx.tcx, it.id);
- check_bounds_are_used(ccx, t.span, &generics.ty_params, tpt_ty);
+ let pty_ty = ty::node_id_to_type(ccx.tcx, it.id);
+ check_bounds_are_used(ccx, t.span, &generics.ty_params, pty_ty);
}
ast::ItemForeignMod(ref m) => {
if m.abi == abi::RustIntrinsic {
}
} else {
for item in m.items.iter() {
- let tpt = ty::lookup_item_type(ccx.tcx, local_def(item.id));
- if !tpt.generics.types.is_empty() {
+ let pty = ty::lookup_item_type(ccx.tcx, local_def(item.id));
+ if !pty.generics.types.is_empty() {
ccx.tcx.sess.span_err(item.span, "foreign items may not have type parameters");
}
impl<'a> AstConv for FnCtxt<'a> {
fn tcx<'a>(&'a self) -> &'a ty::ctxt { self.ccx.tcx }
- fn get_item_ty(&self, id: ast::DefId) -> ty::ty_param_bounds_and_ty {
+ fn get_item_ty(&self, id: ast::DefId) -> ty::Polytype {
ty::lookup_item_type(self.tcx(), id)
}
pub fn impl_self_ty(vcx: &VtableContext,
span: Span, // (potential) receiver for this impl
did: ast::DefId)
- -> ty_param_substs_and_ty {
+ -> TypeAndSubsts {
let tcx = vcx.tcx();
let ity = ty::lookup_item_type(tcx, did);
let substs = subst::Substs::new_type(tps, rps);
let substd_ty = raw_ty.subst(tcx, &substs);
- ty_param_substs_and_ty { substs: substs, ty: substd_ty }
+ TypeAndSubsts { substs: substs, ty: substd_ty }
}
// Only for fields! Returns <none> for methods>
}
ast::ExprPath(ref pth) => {
let defn = lookup_def(fcx, pth.span, id);
- let tpt = ty_param_bounds_and_ty_for_def(fcx, expr.span, defn);
- instantiate_path(fcx, pth, tpt, defn, expr.span, expr.id);
+ let pty = polytype_for_def(fcx, expr.span, defn);
+ instantiate_path(fcx, pth, pty, defn, expr.span, expr.id);
}
ast::ExprInlineAsm(ref ia) => {
for &(_, ref input) in ia.inputs.iter() {
}
// Returns the type parameter count and the type for the given definition.
-pub fn ty_param_bounds_and_ty_for_def(fcx: &FnCtxt,
- sp: Span,
- defn: def::Def)
- -> ty_param_bounds_and_ty {
+pub fn polytype_for_def(fcx: &FnCtxt,
+ sp: Span,
+ defn: def::Def)
+ -> Polytype {
match defn {
def::DefArg(nid, _) | def::DefLocal(nid, _) |
def::DefBinding(nid, _) => {
return ty::lookup_item_type(fcx.ccx.tcx, id);
}
def::DefUpvar(_, inner, _, _) => {
- return ty_param_bounds_and_ty_for_def(fcx, sp, *inner);
+ return polytype_for_def(fcx, sp, *inner);
}
def::DefTrait(_) |
def::DefTy(_) |
// number of type parameters and type.
pub fn instantiate_path(fcx: &FnCtxt,
path: &ast::Path,
- polytype: ty_param_bounds_and_ty,
+ polytype: Polytype,
def: def::Def,
span: Span,
node_id: ast::NodeId) {
use middle::typeck::{vtable_static, vtable_param, vtable_error};
use middle::typeck::{param_index};
use middle::typeck::MethodCall;
+use middle::typeck::TypeAndSubsts;
use middle::subst;
use middle::subst::{Subst, VecPerParamSpace};
use util::common::indenter;
// FIXME: document a bit more what this means
//
// FIXME(#5781) this should be mk_eqty not mk_subty
- let ty::ty_param_substs_and_ty {
+ let TypeAndSubsts {
substs: substs,
ty: for_ty
} = impl_self_ty(vcx, span, impl_did);
use middle::ty::{ImplContainer, lookup_item_type};
use middle::ty::{t, ty_bool, ty_char, ty_bot, ty_box, ty_enum, ty_err};
use middle::ty::{ty_str, ty_vec, ty_float, ty_infer, ty_int, ty_nil};
-use middle::ty::{ty_param, ty_param_bounds_and_ty, ty_ptr};
+use middle::ty::{ty_param, Polytype, ty_ptr};
use middle::ty::{ty_rptr, ty_struct, ty_trait, ty_tup};
use middle::ty::{ty_uint, ty_uniq, ty_bare_fn, ty_closure};
use middle::ty::type_is_ty_var;
// construct the polytype for the method based on the
// method_ty. it will have all the generics from the
// impl, plus its own.
- let new_polytype = ty::ty_param_bounds_and_ty {
+ let new_polytype = ty::Polytype {
generics: new_method_ty.generics.clone(),
ty: ty::mk_bare_fn(tcx, new_method_ty.fty.clone())
};
}
fn polytypes_unify(&self,
- polytype_a: ty_param_bounds_and_ty,
- polytype_b: ty_param_bounds_and_ty)
+ polytype_a: Polytype,
+ polytype_b: Polytype)
-> bool {
let universally_quantified_a =
self.universally_quantify_polytype(polytype_a);
// Converts a polytype to a monotype by replacing all parameters with
// type variables. Returns the monotype and the type variables created.
- fn universally_quantify_polytype(&self, polytype: ty_param_bounds_and_ty)
+ fn universally_quantify_polytype(&self, polytype: Polytype)
-> UniversalQuantificationResult
{
let substitutions =
}
fn get_self_type_for_implementation(&self, impl_did: DefId)
- -> ty_param_bounds_and_ty {
+ -> Polytype {
self.crate_context.tcx.tcache.borrow().get_copy(&impl_did)
}
fn subst_receiver_types_in_method_ty(tcx: &ty::ctxt,
impl_id: ast::DefId,
- impl_poly_type: &ty::ty_param_bounds_and_ty,
+ impl_poly_type: &ty::Polytype,
trait_ref: &ty::TraitRef,
new_def_id: ast::DefId,
method: &ty::Method,
that they are generic types that may have type parameters (more
mathematically phrased, they are universally quantified over a set of
type parameters). Polytypes are represented by an instance of
-`ty::ty_param_bounds_and_ty`. This combines the core type along with
-a list of the bounds for each parameter. Type parameters themselves
-are represented as `ty_param()` instances.
+`ty::Polytype`. This combines the core type along with a list of the
+bounds for each parameter. Type parameters themselves are represented
+as `ty_param()` instances.
*/
use middle::subst;
use middle::subst::{Substs};
use middle::ty::{ImplContainer, MethodContainer, TraitContainer};
-use middle::ty::{ty_param_bounds_and_ty};
+use middle::ty::{Polytype};
use middle::ty;
use middle::typeck::astconv::{AstConv, ty_of_arg};
use middle::typeck::astconv::{ast_ty_to_ty};
pub fn collect_item_types(ccx: &CrateCtxt, krate: &ast::Crate) {
fn collect_intrinsic_type(ccx: &CrateCtxt,
lang_item: ast::DefId) {
- let ty::ty_param_bounds_and_ty { ty: ty, .. } =
+ let ty::Polytype { ty: ty, .. } =
ccx.get_item_ty(lang_item);
ccx.tcx.intrinsic_defs.borrow_mut().insert(lang_item, ty);
}
impl<'a> AstConv for CrateCtxt<'a> {
fn tcx<'a>(&'a self) -> &'a ty::ctxt { self.tcx }
- fn get_item_ty(&self, id: ast::DefId) -> ty::ty_param_bounds_and_ty {
+ fn get_item_ty(&self, id: ast::DefId) -> ty::Polytype {
if id.krate != ast::LOCAL_CRATE {
return csearch::get_type(self.tcx, id)
}
}
ast::StructVariantKind(struct_def) => {
- let tpt = ty_param_bounds_and_ty {
+ let pty = Polytype {
generics: ty_generics_for_type(ccx, generics),
ty: enum_ty
};
- convert_struct(ccx, &*struct_def, tpt, variant.node.id);
+ convert_struct(ccx, &*struct_def, pty, variant.node.id);
let input_tys: Vec<_> = struct_def.fields.iter().map(
|f| ty::node_id_to_type(ccx.tcx, f.node.id)).collect();
}
};
- let tpt = ty_param_bounds_and_ty {
+ let pty = Polytype {
generics: ty_generics_for_type(ccx, generics),
ty: result_ty
};
- tcx.tcache.borrow_mut().insert(local_def(variant.node.id), tpt);
+ tcx.tcache.borrow_mut().insert(local_def(variant.node.id), pty);
write_ty_to_tcx(tcx, variant.node.id, result_ty);
}
fn make_static_method_ty(ccx: &CrateCtxt, m: &ty::Method) {
ccx.tcx.tcache.borrow_mut().insert(
m.def_id,
- ty_param_bounds_and_ty {
+ Polytype {
generics: m.generics.clone(),
ty: ty::mk_bare_fn(ccx.tcx, m.fty.clone()) });
}
write_ty_to_tcx(ccx.tcx, v.node.id, tt);
/* add the field to the tcache */
ccx.tcx.tcache.borrow_mut().insert(local_def(v.node.id),
- ty::ty_param_bounds_and_ty {
+ ty::Polytype {
generics: struct_generics.clone(),
ty: tt
});
fty.repr(ccx.tcx));
tcx.tcache.borrow_mut().insert(
local_def(m.id),
- ty_param_bounds_and_ty {
+ Polytype {
generics: mty.generics.clone(),
ty: fty
});
ast::ItemForeignMod(_) | ast::ItemMod(_) | ast::ItemMac(_) => {}
ast::ItemEnum(ref enum_definition, ref generics) => {
ensure_no_ty_param_bounds(ccx, it.span, generics, "enumeration");
- let tpt = ty_of_item(ccx, it);
- write_ty_to_tcx(tcx, it.id, tpt.ty);
+ let pty = ty_of_item(ccx, it);
+ write_ty_to_tcx(tcx, it.id, pty.ty);
get_enum_variant_types(ccx,
- tpt.ty,
+ pty.ty,
enum_definition.variants.as_slice(),
generics);
},
write_ty_to_tcx(tcx, it.id, selfty);
tcx.tcache.borrow_mut().insert(local_def(it.id),
- ty_param_bounds_and_ty {
+ Polytype {
generics: ty_generics.clone(),
ty: selfty});
ensure_no_ty_param_bounds(ccx, it.span, generics, "structure");
// Write the class type.
- let tpt = ty_of_item(ccx, it);
- write_ty_to_tcx(tcx, it.id, tpt.ty);
+ let pty = ty_of_item(ccx, it);
+ write_ty_to_tcx(tcx, it.id, pty.ty);
- tcx.tcache.borrow_mut().insert(local_def(it.id), tpt.clone());
+ tcx.tcache.borrow_mut().insert(local_def(it.id), pty.clone());
// Write the super-struct type, if it exists.
match struct_def.super_struct {
_ => {},
}
- convert_struct(ccx, &*struct_def, tpt, it.id);
+ convert_struct(ccx, &*struct_def, pty, it.id);
},
ast::ItemTy(_, ref generics) => {
ensure_no_ty_param_bounds(ccx, it.span, generics, "type");
- let tpt = ty_of_item(ccx, it);
- write_ty_to_tcx(tcx, it.id, tpt.ty);
+ let pty = ty_of_item(ccx, it);
+ write_ty_to_tcx(tcx, it.id, pty.ty);
},
ast::ItemFn(_, _, abi, ref generics, _) => {
ensure_generics_abi(ccx, it.span, abi, generics);
- let tpt = ty_of_item(ccx, it);
- write_ty_to_tcx(tcx, it.id, tpt.ty);
+ let pty = ty_of_item(ccx, it);
+ write_ty_to_tcx(tcx, it.id, pty.ty);
},
_ => {
// This call populates the type cache with the converted type
// of the item in passing. All we have to do here is to write
// it into the node type table.
- let tpt = ty_of_item(ccx, it);
- write_ty_to_tcx(tcx, it.id, tpt.ty);
+ let pty = ty_of_item(ccx, it);
+ write_ty_to_tcx(tcx, it.id, pty.ty);
},
}
}
pub fn convert_struct(ccx: &CrateCtxt,
struct_def: &ast::StructDef,
- tpt: ty::ty_param_bounds_and_ty,
+ pty: ty::Polytype,
id: ast::NodeId) {
let tcx = ccx.tcx;
// Write the type of each of the members and check for duplicate fields.
let mut seen_fields: HashMap<ast::Name, Span> = HashMap::new();
let field_tys = struct_def.fields.iter().map(|f| {
- let result = convert_field(ccx, &tpt.generics, f, local_def(id));
+ let result = convert_field(ccx, &pty.generics, f, local_def(id));
if result.name != special_idents::unnamed_field.name {
let dup = match seen_fields.find(&result.name) {
};
tcx.superstructs.borrow_mut().insert(local_def(id), super_struct);
- let substs = mk_item_substs(ccx, &tpt.generics);
+ let substs = mk_item_substs(ccx, &pty.generics);
let selfty = ty::mk_struct(tcx, local_def(id), substs);
// If this struct is enum-like or tuple-like, create the type of its
// Enum-like.
write_ty_to_tcx(tcx, ctor_id, selfty);
- tcx.tcache.borrow_mut().insert(local_def(ctor_id), tpt);
+ tcx.tcache.borrow_mut().insert(local_def(ctor_id), pty);
} else if struct_def.fields.get(0).node.kind.is_unnamed() {
// Tuple-like.
let inputs: Vec<_> = struct_def.fields.iter().map(
selfty);
write_ty_to_tcx(tcx, ctor_id, ctor_fn_ty);
tcx.tcache.borrow_mut().insert(local_def(ctor_id),
- ty_param_bounds_and_ty {
- generics: tpt.generics,
+ Polytype {
+ generics: pty.generics,
ty: ctor_fn_ty
});
}
// convenient way to extract the ABI. - ndm
let abi = ccx.tcx.map.get_foreign_abi(i.id);
- let tpt = ty_of_foreign_item(ccx, i, abi);
- write_ty_to_tcx(ccx.tcx, i.id, tpt.ty);
+ let pty = ty_of_foreign_item(ccx, i, abi);
+ write_ty_to_tcx(ccx.tcx, i.id, pty.ty);
- ccx.tcx.tcache.borrow_mut().insert(local_def(i.id), tpt);
+ ccx.tcx.tcache.borrow_mut().insert(local_def(i.id), pty);
}
pub fn instantiate_trait_ref(ccx: &CrateCtxt,
}
pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::Item)
- -> ty::ty_param_bounds_and_ty {
+ -> ty::Polytype {
let def_id = local_def(it.id);
let tcx = ccx.tcx;
match tcx.tcache.borrow().find(&def_id) {
- Some(tpt) => return tpt.clone(),
+ Some(pty) => return pty.clone(),
_ => {}
}
match it.node {
ast::ItemStatic(t, _, _) => {
let typ = ccx.to_ty(&ExplicitRscope, &*t);
- let tpt = no_params(typ);
+ let pty = no_params(typ);
- tcx.tcache.borrow_mut().insert(local_def(it.id), tpt.clone());
- return tpt;
+ tcx.tcache.borrow_mut().insert(local_def(it.id), pty.clone());
+ return pty;
}
ast::ItemFn(decl, fn_style, abi, ref generics, _) => {
let ty_generics = ty_generics_for_fn_or_method(ccx, generics,
fn_style,
abi,
&*decl);
- let tpt = ty_param_bounds_and_ty {
+ let pty = Polytype {
generics: ty_generics,
ty: ty::mk_bare_fn(ccx.tcx, tofd)
};
debug!("type of {} (id {}) is {}",
token::get_ident(it.ident),
it.id,
- ppaux::ty_to_str(tcx, tpt.ty));
+ ppaux::ty_to_str(tcx, pty.ty));
- ccx.tcx.tcache.borrow_mut().insert(local_def(it.id), tpt.clone());
- return tpt;
+ ccx.tcx.tcache.borrow_mut().insert(local_def(it.id), pty.clone());
+ return pty;
}
ast::ItemTy(t, ref generics) => {
match tcx.tcache.borrow_mut().find(&local_def(it.id)) {
- Some(tpt) => return tpt.clone(),
+ Some(pty) => return pty.clone(),
None => { }
}
- let tpt = {
+ let pty = {
let ty = ccx.to_ty(&ExplicitRscope, &*t);
- ty_param_bounds_and_ty {
+ Polytype {
generics: ty_generics_for_type(ccx, generics),
ty: ty
}
};
- tcx.tcache.borrow_mut().insert(local_def(it.id), tpt.clone());
- return tpt;
+ tcx.tcache.borrow_mut().insert(local_def(it.id), pty.clone());
+ return pty;
}
ast::ItemEnum(_, ref generics) => {
// Create a new generic polytype.
let ty_generics = ty_generics_for_type(ccx, generics);
let substs = mk_item_substs(ccx, &ty_generics);
let t = ty::mk_enum(tcx, local_def(it.id), substs);
- let tpt = ty_param_bounds_and_ty {
+ let pty = Polytype {
generics: ty_generics,
ty: t
};
- tcx.tcache.borrow_mut().insert(local_def(it.id), tpt.clone());
- return tpt;
+ tcx.tcache.borrow_mut().insert(local_def(it.id), pty.clone());
+ return pty;
}
ast::ItemTrait(..) => {
tcx.sess.span_bug(it.span, "invoked ty_of_item on trait");
let ty_generics = ty_generics_for_type(ccx, generics);
let substs = mk_item_substs(ccx, &ty_generics);
let t = ty::mk_struct(tcx, local_def(it.id), substs);
- let tpt = ty_param_bounds_and_ty {
+ let pty = Polytype {
generics: ty_generics,
ty: t
};
- tcx.tcache.borrow_mut().insert(local_def(it.id), tpt.clone());
- return tpt;
+ tcx.tcache.borrow_mut().insert(local_def(it.id), pty.clone());
+ return pty;
}
ast::ItemImpl(..) | ast::ItemMod(_) |
ast::ItemForeignMod(_) | ast::ItemMac(_) => fail!(),
pub fn ty_of_foreign_item(ccx: &CrateCtxt,
it: &ast::ForeignItem,
- abi: abi::Abi) -> ty::ty_param_bounds_and_ty
+ abi: abi::Abi) -> ty::Polytype
{
match it.node {
ast::ForeignItemFn(fn_decl, ref generics) => {
abi)
}
ast::ForeignItemStatic(t, _) => {
- ty::ty_param_bounds_and_ty {
+ ty::Polytype {
generics: ty::Generics::empty(),
ty: ast_ty_to_ty(ccx, &ExplicitRscope, &*t)
}
def_id: ast::DefId,
ast_generics: &ast::Generics,
abi: abi::Abi)
- -> ty::ty_param_bounds_and_ty {
+ -> ty::Polytype {
for i in decl.inputs.iter() {
match (*i).pat.node {
output: output_ty,
variadic: decl.variadic}
});
- let tpt = ty_param_bounds_and_ty {
+ let pty = Polytype {
generics: ty_generics_for_fn_or_method,
ty: t_fn
};
- ccx.tcx.tcache.borrow_mut().insert(def_id, tpt.clone());
- return tpt;
+ ccx.tcx.tcache.borrow_mut().insert(def_id, pty.clone());
+ return pty;
}
pub fn mk_item_substs(ccx: &CrateCtxt,
};
match a_def {
def::DefTy(did) | def::DefStruct(did) => {
- let ty::ty_param_bounds_and_ty {
+ let ty::Polytype {
generics: generics,
ty: _
} = ty::lookup_item_type(self.tcx, did);
AutoObject
}
+pub struct TypeAndSubsts {
+ pub substs: subst::Substs,
+ pub ty: ty::t,
+}
+
impl MethodCall {
pub fn expr(id: ast::NodeId) -> MethodCall {
MethodCall {
lookup_def_tcx(ccx.tcx, sp, id)
}
-pub fn no_params(t: ty::t) -> ty::ty_param_bounds_and_ty {
- ty::ty_param_bounds_and_ty {
+pub fn no_params(t: ty::t) -> ty::Polytype {
+ ty::Polytype {
generics: ty::Generics {types: VecPerParamSpace::empty(),
regions: VecPerParamSpace::empty()},
ty: t
}
}
-impl Repr for ty::ty_param_bounds_and_ty {
+impl Repr for ty::Polytype {
fn repr(&self, tcx: &ctxt) -> String {
- format!("ty_param_bounds_and_ty {{generics: {}, ty: {}}}",
+ format!("Polytype {{generics: {}, ty: {}}}",
self.generics.repr(tcx),
self.ty.repr(tcx))
}
let to_encode_object = TestStruct{data_str:"example of string to encode".to_string()};
let mut m = io::MemWriter::new();
{
- let mut encoder = json::Encoder::new(&mut m as &mut std::io::Writer);
+ let mut encoder = json::Encoder::new(&mut m as &mut Writer);
match to_encode_object.encode(&mut encoder) {
Ok(()) => (),
Err(e) => fail!("json encoding error: {}", e)
impl MemWriter {
/// Create a new `MemWriter`.
+ #[inline]
pub fn new() -> MemWriter {
MemWriter::with_capacity(128)
}
/// Create a new `MemWriter`, allocating at least `n` bytes for
/// the internal buffer.
+ #[inline]
pub fn with_capacity(n: uint) -> MemWriter {
MemWriter { buf: Vec::with_capacity(n), pos: 0 }
}
///
/// No method is exposed for acquiring a mutable reference to the buffer
/// because it could corrupt the state of this `MemWriter`.
+ #[inline]
pub fn get_ref<'a>(&'a self) -> &'a [u8] { self.buf.as_slice() }
/// Unwraps this `MemWriter`, returning the underlying buffer
+ #[inline]
pub fn unwrap(self) -> Vec<u8> { self.buf }
}
impl Writer for MemWriter {
+ #[inline]
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
// Make sure the internal buffer is as least as big as where we
// currently are
}
impl Seek for MemWriter {
+ #[inline]
fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
+
+ #[inline]
fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
let new = try!(combine(style, self.pos, self.buf.len(), pos));
self.pos = new as uint;
impl MemReader {
/// Creates a new `MemReader` which will read the buffer given. The buffer
/// can be re-acquired through `unwrap`
+ #[inline]
pub fn new(buf: Vec<u8>) -> MemReader {
MemReader {
buf: buf,
/// Tests whether this reader has read all bytes in its buffer.
///
/// If `true`, then this will no longer return bytes from `read`.
+ #[inline]
pub fn eof(&self) -> bool { self.pos >= self.buf.len() }
/// Acquires an immutable reference to the underlying buffer of this
///
/// No method is exposed for acquiring a mutable reference to the buffer
/// because it could corrupt the state of this `MemReader`.
+ #[inline]
pub fn get_ref<'a>(&'a self) -> &'a [u8] { self.buf.as_slice() }
/// Unwraps this `MemReader`, returning the underlying buffer
+ #[inline]
pub fn unwrap(self) -> Vec<u8> { self.buf }
}
impl Reader for MemReader {
+ #[inline]
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
if self.eof() { return Err(io::standard_error(io::EndOfFile)) }
}
impl Seek for MemReader {
+ #[inline]
fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
+
+ #[inline]
fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
let new = try!(combine(style, self.pos, self.buf.len(), pos));
self.pos = new as uint;
}
impl Buffer for MemReader {
+ #[inline]
fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
if self.pos < self.buf.len() {
Ok(self.buf.slice_from(self.pos))
Err(io::standard_error(io::EndOfFile))
}
}
+
+ #[inline]
fn consume(&mut self, amt: uint) { self.pos += amt; }
}
impl<'a> BufWriter<'a> {
/// Creates a new `BufWriter` which will wrap the specified buffer. The
/// writer initially starts at position 0.
+ #[inline]
pub fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a> {
BufWriter {
buf: buf,
}
impl<'a> Writer for BufWriter<'a> {
+ #[inline]
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
// return an error if the entire write does not fit in the buffer
let max_size = self.buf.len();
}
impl<'a> Seek for BufWriter<'a> {
+ #[inline]
fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
+
+ #[inline]
fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
let new = try!(combine(style, self.pos, self.buf.len(), pos));
self.pos = new as uint;
impl<'a> BufReader<'a> {
/// Creates a new buffered reader which will read the specified buffer
+ #[inline]
pub fn new<'a>(buf: &'a [u8]) -> BufReader<'a> {
BufReader {
buf: buf,
/// Tests whether this reader has read all bytes in its buffer.
///
/// If `true`, then this will no longer return bytes from `read`.
+ #[inline]
pub fn eof(&self) -> bool { self.pos >= self.buf.len() }
}
impl<'a> Reader for BufReader<'a> {
+ #[inline]
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
if self.eof() { return Err(io::standard_error(io::EndOfFile)) }
}
impl<'a> Seek for BufReader<'a> {
+ #[inline]
fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
+
+ #[inline]
fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
let new = try!(combine(style, self.pos, self.buf.len(), pos));
self.pos = new as uint;
}
impl<'a> Buffer for BufReader<'a> {
+ #[inline]
fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
if self.pos < self.buf.len() {
Ok(self.buf.slice_from(self.pos))
Err(io::standard_error(io::EndOfFile))
}
}
+
+ #[inline]
fn consume(&mut self, amt: uint) { self.pos += amt; }
}
#[cfg(test)]
mod test {
+ extern crate test;
use prelude::*;
use super::*;
use io::*;
use io;
+ use self::test::Bencher;
use str::StrSlice;
#[test]
assert!(r.read_at_least(buf.len(), buf).is_err());
assert_eq!(buf.as_slice(), &[7, 8, 6]);
}
+
+ #[bench]
+ fn bench_mem_writer(b: &mut Bencher) {
+ b.iter(|| {
+ let mut wr = MemWriter::new();
+ for _i in range(0, 10) {
+ wr.write([5, .. 10]).unwrap();
+ }
+ assert_eq!(wr.unwrap().as_slice(), [5, .. 100].as_slice());
+ });
+ }
+
+ #[bench]
+ fn bench_mem_reader(b: &mut Bencher) {
+ b.iter(|| {
+ let buf = Vec::from_slice([5 as u8, ..100]);
+ {
+ let mut rdr = MemReader::new(buf);
+ for _i in range(0, 10) {
+ let mut buf = [0 as u8, .. 10];
+ rdr.read(buf).unwrap();
+ assert_eq!(buf.as_slice(), [5, .. 10].as_slice());
+ }
+ }
+ });
+ }
+
+ #[bench]
+ fn bench_buf_writer(b: &mut Bencher) {
+ b.iter(|| {
+ let mut buf = [0 as u8, ..100];
+ {
+ let mut wr = BufWriter::new(buf);
+ for _i in range(0, 10) {
+ wr.write([5, .. 10]).unwrap();
+ }
+ }
+ assert_eq!(buf.as_slice(), [5, .. 100].as_slice());
+ });
+ }
+
+ #[bench]
+ fn bench_buf_reader(b: &mut Bencher) {
+ b.iter(|| {
+ let buf = [5 as u8, ..100];
+ {
+ let mut rdr = BufReader::new(buf);
+ for _i in range(0, 10) {
+ let mut buf = [0 as u8, .. 10];
+ rdr.read(buf).unwrap();
+ assert_eq!(buf.as_slice(), [5, .. 10].as_slice());
+ }
+ }
+ });
+ }
}
/// If other encodings are desired, it is recommended to compose this stream
/// with another performing the conversion, or to use `write` with a
/// converted byte-array instead.
+ #[inline]
fn write_str(&mut self, s: &str) -> IoResult<()> {
self.write(s.as_bytes())
}
///
/// If other encodings or line ending flavors are desired, it is recommended
/// that the `write` method is used specifically instead.
+ #[inline]
fn write_line(&mut self, s: &str) -> IoResult<()> {
self.write_str(s).and_then(|()| self.write(['\n' as u8]))
}
/// Write a single char, encoded as UTF-8.
+ #[inline]
fn write_char(&mut self, c: char) -> IoResult<()> {
let mut buf = [0u8, ..4];
let n = c.encode_utf8(buf.as_mut_slice());
}
/// Write the result of passing n through `int::to_str_bytes`.
+ #[inline]
fn write_int(&mut self, n: int) -> IoResult<()> {
write!(self, "{:d}", n)
}
/// Write the result of passing n through `uint::to_str_bytes`.
+ #[inline]
fn write_uint(&mut self, n: uint) -> IoResult<()> {
write!(self, "{:u}", n)
}
/// Write a little-endian uint (number of bytes depends on system).
+ #[inline]
fn write_le_uint(&mut self, n: uint) -> IoResult<()> {
extensions::u64_to_le_bytes(n as u64, uint::BYTES, |v| self.write(v))
}
/// Write a little-endian int (number of bytes depends on system).
+ #[inline]
fn write_le_int(&mut self, n: int) -> IoResult<()> {
extensions::u64_to_le_bytes(n as u64, int::BYTES, |v| self.write(v))
}
/// Write a big-endian uint (number of bytes depends on system).
+ #[inline]
fn write_be_uint(&mut self, n: uint) -> IoResult<()> {
extensions::u64_to_be_bytes(n as u64, uint::BYTES, |v| self.write(v))
}
/// Write a big-endian int (number of bytes depends on system).
+ #[inline]
fn write_be_int(&mut self, n: int) -> IoResult<()> {
extensions::u64_to_be_bytes(n as u64, int::BYTES, |v| self.write(v))
}
/// Write a big-endian u64 (8 bytes).
+ #[inline]
fn write_be_u64(&mut self, n: u64) -> IoResult<()> {
extensions::u64_to_be_bytes(n, 8u, |v| self.write(v))
}
/// Write a big-endian u32 (4 bytes).
+ #[inline]
fn write_be_u32(&mut self, n: u32) -> IoResult<()> {
extensions::u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
}
/// Write a big-endian u16 (2 bytes).
+ #[inline]
fn write_be_u16(&mut self, n: u16) -> IoResult<()> {
extensions::u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
}
/// Write a big-endian i64 (8 bytes).
+ #[inline]
fn write_be_i64(&mut self, n: i64) -> IoResult<()> {
extensions::u64_to_be_bytes(n as u64, 8u, |v| self.write(v))
}
/// Write a big-endian i32 (4 bytes).
+ #[inline]
fn write_be_i32(&mut self, n: i32) -> IoResult<()> {
extensions::u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
}
/// Write a big-endian i16 (2 bytes).
+ #[inline]
fn write_be_i16(&mut self, n: i16) -> IoResult<()> {
extensions::u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
}
/// Write a big-endian IEEE754 double-precision floating-point (8 bytes).
+ #[inline]
fn write_be_f64(&mut self, f: f64) -> IoResult<()> {
unsafe {
self.write_be_u64(transmute(f))
}
/// Write a big-endian IEEE754 single-precision floating-point (4 bytes).
+ #[inline]
fn write_be_f32(&mut self, f: f32) -> IoResult<()> {
unsafe {
self.write_be_u32(transmute(f))
}
/// Write a little-endian u64 (8 bytes).
+ #[inline]
fn write_le_u64(&mut self, n: u64) -> IoResult<()> {
extensions::u64_to_le_bytes(n, 8u, |v| self.write(v))
}
/// Write a little-endian u32 (4 bytes).
+ #[inline]
fn write_le_u32(&mut self, n: u32) -> IoResult<()> {
extensions::u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
}
/// Write a little-endian u16 (2 bytes).
+ #[inline]
fn write_le_u16(&mut self, n: u16) -> IoResult<()> {
extensions::u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
}
/// Write a little-endian i64 (8 bytes).
+ #[inline]
fn write_le_i64(&mut self, n: i64) -> IoResult<()> {
extensions::u64_to_le_bytes(n as u64, 8u, |v| self.write(v))
}
/// Write a little-endian i32 (4 bytes).
+ #[inline]
fn write_le_i32(&mut self, n: i32) -> IoResult<()> {
extensions::u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
}
/// Write a little-endian i16 (2 bytes).
+ #[inline]
fn write_le_i16(&mut self, n: i16) -> IoResult<()> {
extensions::u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
}
/// Write a little-endian IEEE754 double-precision floating-point
/// (8 bytes).
+ #[inline]
fn write_le_f64(&mut self, f: f64) -> IoResult<()> {
unsafe {
self.write_le_u64(transmute(f))
/// Write a little-endian IEEE754 single-precision floating-point
/// (4 bytes).
+ #[inline]
fn write_le_f32(&mut self, f: f32) -> IoResult<()> {
unsafe {
self.write_le_u32(transmute(f))
}
/// Write a u8 (1 byte).
+ #[inline]
fn write_u8(&mut self, n: u8) -> IoResult<()> {
self.write([n])
}
/// Write an i8 (1 byte).
+ #[inline]
fn write_i8(&mut self, n: i8) -> IoResult<()> {
self.write([n as u8])
}
///
/// This is useful to allow applying wrappers while still
/// retaining ownership of the original value.
+ #[inline]
fn by_ref<'a>(&'a mut self) -> RefWriter<'a, Self> {
RefWriter { inner: self }
}
}
impl Writer for Box<Writer> {
+ #[inline]
fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.write(buf) }
+
+ #[inline]
fn flush(&mut self) -> IoResult<()> { self.flush() }
}
impl<'a> Writer for &'a mut Writer {
+ #[inline]
fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.write(buf) }
+
+ #[inline]
fn flush(&mut self) -> IoResult<()> { self.flush() }
}
}
impl<'a, W: Writer> Writer for RefWriter<'a, W> {
+ #[inline]
fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.inner.write(buf) }
+
+ #[inline]
fn flush(&mut self) -> IoResult<()> { self.inner.flush() }
}
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+ let mut x = &[1, 2, 3, 4];
+
+ let mut result = vec!();
+ loop {
+ x = match x {
+ [1, n, 3, ..rest] => {
+ result.push(n);
+ rest
+ }
+ [n, ..rest] => {
+ result.push(n);
+ rest
+ }
+ [] =>
+ break
+ }
+ }
+ assert!(result.as_slice() == [2, 4]);
+}
assert_eq!(branch, 1);
}
+fn e() {
+ match &[1, 2, 3] {
+ [1, 2] => (),
+ [..] => ()
+ }
+}
+
pub fn main() {
a();
b();
c();
d();
+ e();
}