From bc6848d352dd234ffb9c6cb97e2fbcf6c878c8d8 Mon Sep 17 00:00:00 2001 From: Jens Nockert Date: Mon, 17 Jun 2013 02:05:36 +0200 Subject: [PATCH 01/93] Adds conditional byteswapping intrinsics These intrinsics are synthesized, so maybe they should be in another file. But since they are just a single line of code each, based on the bswap intrinsics and aren't really intended for public consumption (they should be exposed as a single function / trait) I thought they would fit here. --- src/libstd/unstable/intrinsics.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index 908c5e23ab07..599ecc3c4658 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -238,3 +238,17 @@ pub extern "rust-intrinsic" { pub fn bswap32(x: i32) -> i32; pub fn bswap64(x: i64) -> i64; } + +#[cfg(target_endian = "little")] pub fn to_le16(x: i16) -> i16 { x } +#[cfg(target_endian = "big")] pub fn to_le16(x: i16) -> i16 { unsafe { bswap16(x) } } +#[cfg(target_endian = "little")] pub fn to_le32(x: i32) -> i32 { x } +#[cfg(target_endian = "big")] pub fn to_le32(x: i32) -> i32 { unsafe { bswap32(x) } } +#[cfg(target_endian = "little")] pub fn to_le64(x: i64) -> i64 { x } +#[cfg(target_endian = "big")] pub fn to_le64(x: i64) -> i64 { unsafe { bswap64(x) } } + +#[cfg(target_endian = "little")] pub fn to_be16(x: i16) -> i16 { unsafe { bswap16(x) } } +#[cfg(target_endian = "big")] pub fn to_be16(x: i16) -> i16 { x } +#[cfg(target_endian = "little")] pub fn to_be32(x: i32) -> i32 { unsafe { bswap32(x) } } +#[cfg(target_endian = "big")] pub fn to_be32(x: i32) -> i32 { x } +#[cfg(target_endian = "little")] pub fn to_be64(x: i64) -> i64 { unsafe { bswap64(x) } } +#[cfg(target_endian = "big")] pub fn to_be64(x: i64) -> i64 { x } From 208eb0f8cbbf6c30d5a4de957bee742c22c307db Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 29 Jun 2013 22:19:32 -0700 Subject: [PATCH 02/93] Implement `map_mut` on the Option type Closes #7394 --- src/libstd/option.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/libstd/option.rs b/src/libstd/option.rs index 643812312582..fb9962f8a44e 100644 --- a/src/libstd/option.rs +++ b/src/libstd/option.rs @@ -161,7 +161,7 @@ impl Option { /// Filters an optional value using given function. #[inline(always)] - pub fn filtered<'a>(self, f: &fn(t: &'a T) -> bool) -> Option { + pub fn filtered(self, f: &fn(t: &T) -> bool) -> Option { match self { Some(x) => if(f(&x)) {Some(x)} else {None}, None => None @@ -170,10 +170,16 @@ impl Option { /// Maps a `some` value from one type to another by reference #[inline] - pub fn map<'a, U>(&self, f: &fn(&'a T) -> U) -> Option { + pub fn map<'a, U>(&'a self, f: &fn(&'a T) -> U) -> Option { match *self { Some(ref x) => Some(f(x)), None => None } } + /// Maps a `some` value from one type to another by a mutable reference + #[inline] + pub fn map_mut<'a, U>(&'a mut self, f: &fn(&'a mut T) -> U) -> Option { + match *self { Some(ref mut x) => Some(f(x)), None => None } + } + /// As `map`, but consumes the option and gives `f` ownership to avoid /// copying. #[inline] From 9c3ef892f90289b6af77cbfe6c50dfb56eeb4c17 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Sat, 29 Jun 2013 22:22:20 -0400 Subject: [PATCH 03/93] configure: Require one of wget or curl. --- configure | 2 +- src/etc/snapshot.py | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/configure b/configure index d0a98fbfa75c..12782fa9fdb6 100755 --- a/configure +++ b/configure @@ -402,7 +402,7 @@ fi step_msg "looking for build programs" probe_need CFG_PERL perl -probe_need CFG_CURL curl +probe_need CFG_CURLORWGET curl wget probe_need CFG_PYTHON python2.7 python2.6 python2 python python_version=$($CFG_PYTHON -V 2>&1) diff --git a/src/etc/snapshot.py b/src/etc/snapshot.py index 608dbdcca5d2..36b00a3dedf2 100644 --- a/src/etc/snapshot.py +++ b/src/etc/snapshot.py @@ -1,6 +1,6 @@ # xfail-license -import re, os, sys, glob, tarfile, shutil, subprocess, tempfile +import re, os, sys, glob, tarfile, shutil, subprocess, tempfile, distutils.spawn try: import hashlib @@ -132,7 +132,13 @@ def local_rev_committer_date(): def get_url_to_file(u,f): # no security issue, just to stop partial download leaving a stale file tmpf = f + '.tmp' - returncode = subprocess.call(["curl", "-o", tmpf, u]) + + returncode = -1 + if distutils.spawn.find_executable("curl"): + returncode = subprocess.call(["curl", "-o", tmpf, u]) + elif distutils.spawn.find_executable("wget"): + returncode = subprocess.call(["wget", "-O", tmpf, u]) + if returncode != 0: os.unlink(tmpf) raise From 31004835e22de0385b2c8ed59ac66be1042c6527 Mon Sep 17 00:00:00 2001 From: gareth Date: Sun, 30 Jun 2013 21:43:53 +0100 Subject: [PATCH 04/93] When an impl references an unknown trait, mention what the trait is called in the error message. --- src/librustc/middle/resolve.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 06147894d446..734eb980001a 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -3831,9 +3831,9 @@ impl Resolver { visitor: ResolveVisitor) { match self.resolve_path(trait_reference.path, TypeNS, true, visitor) { None => { + let idents = self.idents_to_str(trait_reference.path.idents); self.session.span_err(trait_reference.path.span, - "attempt to implement an \ - unknown trait"); + fmt!("attempt to implement an unknown trait `%s`", idents)); } Some(def) => { self.record_def(trait_reference.ref_id, def); From 0fc99f1997be9323bb75826c478094e74797ddf9 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 30 Jun 2013 20:12:04 +0200 Subject: [PATCH 05/93] Add an EnumSetIterator and EnumSet::iter --- src/librustc/util/enum_set.rs | 92 +++++++++++++++++++++++++++++++---- 1 file changed, 83 insertions(+), 9 deletions(-) diff --git a/src/librustc/util/enum_set.rs b/src/librustc/util/enum_set.rs index 2bdb6583b230..7f29ce98b3ec 100644 --- a/src/librustc/util/enum_set.rs +++ b/src/librustc/util/enum_set.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::iterator::Iterator; #[deriving(Eq, IterBytes)] pub struct EnumSet { @@ -73,6 +74,10 @@ impl EnumSet { } return true; } + + pub fn iter(&self) -> EnumSetIterator { + EnumSetIterator::new(self.bits) + } } impl Sub, EnumSet> for EnumSet { @@ -93,6 +98,39 @@ impl BitAnd, EnumSet> for EnumSet { } } +pub struct EnumSetIterator { + priv index: uint, + priv bits: uint, +} + +impl EnumSetIterator { + fn new(bits: uint) -> EnumSetIterator { + EnumSetIterator { index: 0, bits: bits } + } +} + +impl Iterator for EnumSetIterator { + fn next(&mut self) -> Option { + if (self.bits == 0) { + return None; + } + + while (self.bits & 1) == 0 { + self.index += 1; + self.bits >>= 1; + } + let elem = CLike::from_uint(self.index); + self.index += 1; + self.bits >>= 1; + Some(elem) + } + + fn size_hint(&self) -> (Option, Option) { + let exact = Some(self.bits.population_count()); + (exact, exact) + } +} + #[cfg(test)] mod test { @@ -199,25 +237,58 @@ mod test { } /////////////////////////////////////////////////////////////////////////// - // each + // iterator + + #[test] + fn test_iterator() { + let mut e1: EnumSet = EnumSet::empty(); + + let elems: ~[Foo] = e1.iter().collect(); + assert_eq!(~[], elems) + + e1.add(A); + let elems: ~[Foo] = e1.iter().collect(); + assert_eq!(~[A], elems) + + e1.add(C); + let elems: ~[Foo] = e1.iter().collect(); + assert_eq!(~[A,C], elems) + + e1.add(C); + let elems: ~[Foo] = e1.iter().collect(); + assert_eq!(~[A,C], elems) + + e1.add(B); + let elems: ~[Foo] = e1.iter().collect(); + assert_eq!(~[A,B,C], elems) + } + + fn collect(e: EnumSet) -> ~[Foo] { + let mut elems = ~[]; + e.each(|elem| { + elems.push(elem); + true + }); + elems + } #[test] fn test_each() { let mut e1: EnumSet = EnumSet::empty(); - assert_eq!(~[], iter::FromIter::from_iter::(|f| e1.each(f))) + assert_eq!(~[], collect(e1)) e1.add(A); - assert_eq!(~[A], iter::FromIter::from_iter::(|f| e1.each(f))) + assert_eq!(~[A], collect(e1)) e1.add(C); - assert_eq!(~[A,C], iter::FromIter::from_iter::(|f| e1.each(f))) + assert_eq!(~[A,C], collect(e1)) e1.add(C); - assert_eq!(~[A,C], iter::FromIter::from_iter::(|f| e1.each(f))) + assert_eq!(~[A,C], collect(e1)) e1.add(B); - assert_eq!(~[A,B,C], iter::FromIter::from_iter::(|f| e1.each(f))) + assert_eq!(~[A,B,C], collect(e1)) } /////////////////////////////////////////////////////////////////////////// @@ -234,12 +305,15 @@ mod test { e2.add(C); let e_union = e1 | e2; - assert_eq!(~[A,B,C], iter::FromIter::from_iter::(|f| e_union.each(f))) + let elems: ~[Foo] = e_union.iter().collect(); + assert_eq!(~[A,B,C], elems) let e_intersection = e1 & e2; - assert_eq!(~[C], iter::FromIter::from_iter::(|f| e_intersection.each(f))) + let elems: ~[Foo] = e_intersection.iter().collect(); + assert_eq!(~[C], elems) let e_subtract = e1 - e2; - assert_eq!(~[A], iter::FromIter::from_iter::(|f| e_subtract.each(f))) + let elems: ~[Foo] = e_subtract.iter().collect(); + assert_eq!(~[A], elems) } } From 3fe05a987c0d1684b1172ca29c9a9ad79852419e Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sat, 29 Jun 2013 04:09:58 +0200 Subject: [PATCH 06/93] Move most iter functionality to extra, fixes #7343 --- src/libextra/iter.rs | 328 ++++++++++++++++++++++++++++++++++ src/librustc/middle/ty.rs | 3 +- src/librustc/util/enum_set.rs | 21 ++- src/libstd/iter.rs | 307 +------------------------------ src/libstd/prelude.rs | 2 +- src/libstd/vec.rs | 10 -- 6 files changed, 345 insertions(+), 326 deletions(-) create mode 100644 src/libextra/iter.rs diff --git a/src/libextra/iter.rs b/src/libextra/iter.rs new file mode 100644 index 000000000000..ad8dcf98317a --- /dev/null +++ b/src/libextra/iter.rs @@ -0,0 +1,328 @@ +// Copyright 2012 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +/*! Composable internal iterators + +Internal iterators are functions implementing the protocol used by the `for` loop. + +An internal iterator takes `fn(...) -> bool` as a parameter, with returning `false` used to signal +breaking out of iteration. The adaptors in the module work with any such iterator, not just ones +tied to specific traits. For example: + +~~~ {.rust} +println(iter::to_vec(|f| uint::range(0, 20, f)).to_str()); +~~~ + +An external iterator object implementing the interface in the `iterator` module can be used as an +internal iterator by calling the `advance` method. For example: + +~~~ {.rust} +let xs = [0u, 1, 2, 3, 4, 5]; +let ys = [30, 40, 50, 60]; +let mut it = xs.iter().chain(ys.iter()); +for it.advance |&x: &uint| { + println(x.to_str()); +} +~~~ + +Internal iterators provide a subset of the functionality of an external iterator. It's not possible +to interleave them to implement algorithms like `zip`, `union` and `merge`. However, they're often +much easier to implement. + +*/ + +use std::vec; +use std::cmp::Ord; +use std::option::{Option, Some, None}; +use std::num::{One, Zero}; +use std::ops::{Add, Mul}; + +#[allow(missing_doc)] +pub trait FromIter { + /// Build a container with elements from an internal iterator. + /// + /// # Example: + /// + /// ~~~ {.rust} + /// let xs = ~[1, 2, 3]; + /// let ys: ~[int] = do FromIter::from_iter |f| { xs.iter().advance(|x| f(*x)) }; + /// assert_eq!(xs, ys); + /// ~~~ + pub fn from_iter(iter: &fn(f: &fn(T) -> bool) -> bool) -> Self; +} + +/** + * Return true if `predicate` is true for any values yielded by an internal iterator. + * + * Example: + * + * ~~~ {.rust} + * let xs = ~[1u, 2, 3, 4, 5]; + * assert!(any(|&x: &uint| x > 2, |f| xs.iter().advance(f))); + * assert!(!any(|&x: &uint| x > 5, |f| xs.iter().advance(f))); + * ~~~ + */ +#[inline] +pub fn any(predicate: &fn(T) -> bool, + iter: &fn(f: &fn(T) -> bool) -> bool) -> bool { + for iter |x| { + if predicate(x) { + return true; + } + } + return false; +} + +/** + * Return true if `predicate` is true for all values yielded by an internal iterator. + * + * # Example: + * + * ~~~ {.rust} + * assert!(all(|&x: &uint| x < 6, |f| uint::range(1, 6, f))); + * assert!(!all(|&x: &uint| x < 5, |f| uint::range(1, 6, f))); + * ~~~ + */ +#[inline] +pub fn all(predicate: &fn(T) -> bool, + iter: &fn(f: &fn(T) -> bool) -> bool) -> bool { + // If we ever break, iter will return false, so this will only return true + // if predicate returns true for everything. + iter(|x| predicate(x)) +} + +/** + * Return the first element where `predicate` returns `true`. Return `None` if no element is found. + * + * # Example: + * + * ~~~ {.rust} + * let xs = ~[1u, 2, 3, 4, 5, 6]; + * assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.iter().advance(f)).unwrap(), 4); + * ~~~ + */ +#[inline] +pub fn find(predicate: &fn(&T) -> bool, + iter: &fn(f: &fn(T) -> bool) -> bool) -> Option { + for iter |x| { + if predicate(&x) { + return Some(x); + } + } + None +} + +/** + * Return the largest item yielded by an iterator. Return `None` if the iterator is empty. + * + * # Example: + * + * ~~~ {.rust} + * let xs = ~[8, 2, 3, 1, -5, 9, 11, 15]; + * assert_eq!(max(|f| xs.iter().advance(f)).unwrap(), &15); + * ~~~ + */ +#[inline] +pub fn max(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option { + let mut result = None; + for iter |x| { + match result { + Some(ref mut y) => { + if x > *y { + *y = x; + } + } + None => result = Some(x) + } + } + result +} + +/** + * Return the smallest item yielded by an iterator. Return `None` if the iterator is empty. + * + * # Example: + * + * ~~~ {.rust} + * let xs = ~[8, 2, 3, 1, -5, 9, 11, 15]; + * assert_eq!(max(|f| xs.iter().advance(f)).unwrap(), &-5); + * ~~~ + */ +#[inline] +pub fn min(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option { + let mut result = None; + for iter |x| { + match result { + Some(ref mut y) => { + if x < *y { + *y = x; + } + } + None => result = Some(x) + } + } + result +} + +/** + * Reduce an iterator to an accumulated value. + * + * # Example: + * + * ~~~ {.rust} + * assert_eq!(fold(0i, |f| int::range(1, 5, f), |a, x| *a += x), 10); + * ~~~ + */ +#[inline] +pub fn fold(start: T, iter: &fn(f: &fn(U) -> bool) -> bool, f: &fn(&mut T, U)) -> T { + let mut result = start; + for iter |x| { + f(&mut result, x); + } + result +} + +/** + * Reduce an iterator to an accumulated value. + * + * `fold_ref` is usable in some generic functions where `fold` is too lenient to type-check, but it + * forces the iterator to yield borrowed pointers. + * + * # Example: + * + * ~~~ {.rust} + * fn product>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T { + * fold_ref(One::one::(), iter, |a, x| *a = a.mul(x)) + * } + * ~~~ + */ +#[inline] +pub fn fold_ref(start: T, iter: &fn(f: &fn(&U) -> bool) -> bool, f: &fn(&mut T, &U)) -> T { + let mut result = start; + for iter |x| { + f(&mut result, x); + } + result +} + +/** + * Return the sum of the items yielding by an iterator. + * + * # Example: + * + * ~~~ {.rust} + * let xs: ~[int] = ~[1, 2, 3, 4]; + * assert_eq!(do sum |f| { xs.iter().advance(f) }, 10); + * ~~~ + */ +#[inline] +pub fn sum>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T { + fold_ref(Zero::zero::(), iter, |a, x| *a = a.add(x)) +} + +/** + * Return the product of the items yielded by an iterator. + * + * # Example: + * + * ~~~ {.rust} + * let xs: ~[int] = ~[1, 2, 3, 4]; + * assert_eq!(do product |f| { xs.iter().advance(f) }, 24); + * ~~~ + */ +#[inline] +pub fn product>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T { + fold_ref(One::one::(), iter, |a, x| *a = a.mul(x)) +} + +impl FromIter for ~[T]{ + #[inline] + pub fn from_iter(iter: &fn(f: &fn(T) -> bool) -> bool) -> ~[T] { + let mut v = ~[]; + for iter |x| { v.push(x) } + v + } +} + +#[cfg(test)] +mod tests { + use super::*; + use prelude::*; + + use int; + use uint; + + #[test] + fn test_from_iter() { + let xs = ~[1, 2, 3]; + let ys: ~[int] = do FromIter::from_iter |f| { xs.iter().advance(|x| f(*x)) }; + assert_eq!(xs, ys); + } + + #[test] + fn test_any() { + let xs = ~[1u, 2, 3, 4, 5]; + assert!(any(|&x: &uint| x > 2, |f| xs.iter().advance(f))); + assert!(!any(|&x: &uint| x > 5, |f| xs.iter().advance(f))); + } + + #[test] + fn test_all() { + assert!(all(|x: uint| x < 6, |f| uint::range(1, 6, f))); + assert!(!all(|x: uint| x < 5, |f| uint::range(1, 6, f))); + } + + #[test] + fn test_find() { + let xs = ~[1u, 2, 3, 4, 5, 6]; + assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.iter().advance(f)).unwrap(), 4); + } + + #[test] + fn test_max() { + let xs = ~[8, 2, 3, 1, -5, 9, 11, 15]; + assert_eq!(max(|f| xs.iter().advance(f)).unwrap(), &15); + } + + #[test] + fn test_min() { + let xs = ~[8, 2, 3, 1, -5, 9, 11, 15]; + assert_eq!(min(|f| xs.iter().advance(f)).unwrap(), &-5); + } + + #[test] + fn test_fold() { + assert_eq!(fold(0i, |f| int::range(1, 5, f), |a, x| *a += x), 10); + } + + #[test] + fn test_sum() { + let xs: ~[int] = ~[1, 2, 3, 4]; + assert_eq!(do sum |f| { xs.iter().advance(f) }, 10); + } + + #[test] + fn test_empty_sum() { + let xs: ~[int] = ~[]; + assert_eq!(do sum |f| { xs.iter().advance(f) }, 0); + } + + #[test] + fn test_product() { + let xs: ~[int] = ~[1, 2, 3, 4]; + assert_eq!(do product |f| { xs.iter().advance(f) }, 24); + } + + #[test] + fn test_empty_product() { + let xs: ~[int] = ~[]; + assert_eq!(do product |f| { xs.iter().advance(f) }, 1); + } +} diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 4ed21d73f3e7..a78143c33cdf 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -29,7 +29,6 @@ use util::enum_set::{EnumSet, CLike}; use std::cast; use std::cmp; use std::hashmap::{HashMap, HashSet}; -use std::iter; use std::ops; use std::ptr::to_unsafe_ptr; use std::to_bytes; @@ -1752,7 +1751,7 @@ pub struct TypeContents { impl TypeContents { pub fn meets_bounds(&self, cx: ctxt, bbs: BuiltinBounds) -> bool { - iter::all(|bb| self.meets_bound(cx, bb), |f| bbs.each(f)) + bbs.iter().all(|bb| self.meets_bound(cx, bb)) } pub fn meets_bound(&self, cx: ctxt, bb: BuiltinBound) -> bool { diff --git a/src/librustc/util/enum_set.rs b/src/librustc/util/enum_set.rs index 7f29ce98b3ec..f9bd7a3508ed 100644 --- a/src/librustc/util/enum_set.rs +++ b/src/librustc/util/enum_set.rs @@ -135,7 +135,6 @@ impl Iterator for EnumSetIterator { mod test { use std::cast; - use std::iter; use util::enum_set::*; @@ -237,7 +236,7 @@ mod test { } /////////////////////////////////////////////////////////////////////////// - // iterator + // iter / each #[test] fn test_iterator() { @@ -263,15 +262,6 @@ mod test { assert_eq!(~[A,B,C], elems) } - fn collect(e: EnumSet) -> ~[Foo] { - let mut elems = ~[]; - e.each(|elem| { - elems.push(elem); - true - }); - elems - } - #[test] fn test_each() { let mut e1: EnumSet = EnumSet::empty(); @@ -291,6 +281,15 @@ mod test { assert_eq!(~[A,B,C], collect(e1)) } + fn collect(e: EnumSet) -> ~[Foo] { + let mut elems = ~[]; + e.each(|elem| { + elems.push(elem); + true + }); + elems + } + /////////////////////////////////////////////////////////////////////////// // operators diff --git a/src/libstd/iter.rs b/src/libstd/iter.rs index 4e598a4aa1cd..2092ae588d01 100644 --- a/src/libstd/iter.rs +++ b/src/libstd/iter.rs @@ -8,316 +8,19 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -/*! Composable internal iterators - -Internal iterators are functions implementing the protocol used by the `for` loop. - -An internal iterator takes `fn(...) -> bool` as a parameter, with returning `false` used to signal -breaking out of iteration. The adaptors in the module work with any such iterator, not just ones -tied to specific traits. For example: +/*! Times trait ~~~ {.rust} -println(iter::to_vec(|f| uint::range(0, 20, f)).to_str()); +use iter::Times; +let ten = 10 as uint; +let mut accum = 0; +for ten.times { accum += 1; } ~~~ -An external iterator object implementing the interface in the `iterator` module can be used as an -internal iterator by calling the `advance` method. For example: - -~~~ {.rust} -let xs = [0u, 1, 2, 3, 4, 5]; -let ys = [30, 40, 50, 60]; -let mut it = xs.iter().chain(ys.iter()); -for it.advance |&x: &uint| { - println(x.to_str()); -} -~~~ - -Internal iterators provide a subset of the functionality of an external iterator. It's not possible -to interleave them to implement algorithms like `zip`, `union` and `merge`. However, they're often -much easier to implement. - */ -use cmp::Ord; -use option::{Option, Some, None}; -use num::{One, Zero}; -use ops::{Add, Mul}; - #[allow(missing_doc)] pub trait Times { fn times(&self, it: &fn() -> bool) -> bool; } -#[allow(missing_doc)] -pub trait FromIter { - /// Build a container with elements from an internal iterator. - /// - /// # Example: - /// - /// ~~~ {.rust} - /// let xs = ~[1, 2, 3]; - /// let ys: ~[int] = do FromIter::from_iter |f| { xs.iter().advance(|x| f(*x)) }; - /// assert_eq!(xs, ys); - /// ~~~ - pub fn from_iter(iter: &fn(f: &fn(T) -> bool) -> bool) -> Self; -} - -/** - * Return true if `predicate` is true for any values yielded by an internal iterator. - * - * Example: - * - * ~~~ {.rust} - * let xs = ~[1u, 2, 3, 4, 5]; - * assert!(any(|&x: &uint| x > 2, |f| xs.iter().advance(f))); - * assert!(!any(|&x: &uint| x > 5, |f| xs.iter().advance(f))); - * ~~~ - */ -#[inline] -pub fn any(predicate: &fn(T) -> bool, - iter: &fn(f: &fn(T) -> bool) -> bool) -> bool { - for iter |x| { - if predicate(x) { - return true; - } - } - return false; -} - -/** - * Return true if `predicate` is true for all values yielded by an internal iterator. - * - * # Example: - * - * ~~~ {.rust} - * assert!(all(|&x: &uint| x < 6, |f| uint::range(1, 6, f))); - * assert!(!all(|&x: &uint| x < 5, |f| uint::range(1, 6, f))); - * ~~~ - */ -#[inline] -pub fn all(predicate: &fn(T) -> bool, - iter: &fn(f: &fn(T) -> bool) -> bool) -> bool { - // If we ever break, iter will return false, so this will only return true - // if predicate returns true for everything. - iter(|x| predicate(x)) -} - -/** - * Return the first element where `predicate` returns `true`. Return `None` if no element is found. - * - * # Example: - * - * ~~~ {.rust} - * let xs = ~[1u, 2, 3, 4, 5, 6]; - * assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.iter().advance(f)).unwrap(), 4); - * ~~~ - */ -#[inline] -pub fn find(predicate: &fn(&T) -> bool, - iter: &fn(f: &fn(T) -> bool) -> bool) -> Option { - for iter |x| { - if predicate(&x) { - return Some(x); - } - } - None -} - -/** - * Return the largest item yielded by an iterator. Return `None` if the iterator is empty. - * - * # Example: - * - * ~~~ {.rust} - * let xs = ~[8, 2, 3, 1, -5, 9, 11, 15]; - * assert_eq!(max(|f| xs.iter().advance(f)).unwrap(), &15); - * ~~~ - */ -#[inline] -pub fn max(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option { - let mut result = None; - for iter |x| { - match result { - Some(ref mut y) => { - if x > *y { - *y = x; - } - } - None => result = Some(x) - } - } - result -} - -/** - * Return the smallest item yielded by an iterator. Return `None` if the iterator is empty. - * - * # Example: - * - * ~~~ {.rust} - * let xs = ~[8, 2, 3, 1, -5, 9, 11, 15]; - * assert_eq!(max(|f| xs.iter().advance(f)).unwrap(), &-5); - * ~~~ - */ -#[inline] -pub fn min(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option { - let mut result = None; - for iter |x| { - match result { - Some(ref mut y) => { - if x < *y { - *y = x; - } - } - None => result = Some(x) - } - } - result -} - -/** - * Reduce an iterator to an accumulated value. - * - * # Example: - * - * ~~~ {.rust} - * assert_eq!(fold(0i, |f| int::range(1, 5, f), |a, x| *a += x), 10); - * ~~~ - */ -#[inline] -pub fn fold(start: T, iter: &fn(f: &fn(U) -> bool) -> bool, f: &fn(&mut T, U)) -> T { - let mut result = start; - for iter |x| { - f(&mut result, x); - } - result -} - -/** - * Reduce an iterator to an accumulated value. - * - * `fold_ref` is usable in some generic functions where `fold` is too lenient to type-check, but it - * forces the iterator to yield borrowed pointers. - * - * # Example: - * - * ~~~ {.rust} - * fn product>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T { - * fold_ref(One::one::(), iter, |a, x| *a = a.mul(x)) - * } - * ~~~ - */ -#[inline] -pub fn fold_ref(start: T, iter: &fn(f: &fn(&U) -> bool) -> bool, f: &fn(&mut T, &U)) -> T { - let mut result = start; - for iter |x| { - f(&mut result, x); - } - result -} - -/** - * Return the sum of the items yielding by an iterator. - * - * # Example: - * - * ~~~ {.rust} - * let xs: ~[int] = ~[1, 2, 3, 4]; - * assert_eq!(do sum |f| { xs.iter().advance(f) }, 10); - * ~~~ - */ -#[inline] -pub fn sum>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T { - fold_ref(Zero::zero::(), iter, |a, x| *a = a.add(x)) -} - -/** - * Return the product of the items yielded by an iterator. - * - * # Example: - * - * ~~~ {.rust} - * let xs: ~[int] = ~[1, 2, 3, 4]; - * assert_eq!(do product |f| { xs.iter().advance(f) }, 24); - * ~~~ - */ -#[inline] -pub fn product>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T { - fold_ref(One::one::(), iter, |a, x| *a = a.mul(x)) -} - -#[cfg(test)] -mod tests { - use super::*; - use prelude::*; - - use int; - use uint; - - #[test] - fn test_from_iter() { - let xs = ~[1, 2, 3]; - let ys: ~[int] = do FromIter::from_iter |f| { xs.iter().advance(|x| f(*x)) }; - assert_eq!(xs, ys); - } - - #[test] - fn test_any() { - let xs = ~[1u, 2, 3, 4, 5]; - assert!(any(|&x: &uint| x > 2, |f| xs.iter().advance(f))); - assert!(!any(|&x: &uint| x > 5, |f| xs.iter().advance(f))); - } - - #[test] - fn test_all() { - assert!(all(|x: uint| x < 6, |f| uint::range(1, 6, f))); - assert!(!all(|x: uint| x < 5, |f| uint::range(1, 6, f))); - } - - #[test] - fn test_find() { - let xs = ~[1u, 2, 3, 4, 5, 6]; - assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.iter().advance(f)).unwrap(), 4); - } - - #[test] - fn test_max() { - let xs = ~[8, 2, 3, 1, -5, 9, 11, 15]; - assert_eq!(max(|f| xs.iter().advance(f)).unwrap(), &15); - } - - #[test] - fn test_min() { - let xs = ~[8, 2, 3, 1, -5, 9, 11, 15]; - assert_eq!(min(|f| xs.iter().advance(f)).unwrap(), &-5); - } - - #[test] - fn test_fold() { - assert_eq!(fold(0i, |f| int::range(1, 5, f), |a, x| *a += x), 10); - } - - #[test] - fn test_sum() { - let xs: ~[int] = ~[1, 2, 3, 4]; - assert_eq!(do sum |f| { xs.iter().advance(f) }, 10); - } - - #[test] - fn test_empty_sum() { - let xs: ~[int] = ~[]; - assert_eq!(do sum |f| { xs.iter().advance(f) }, 0); - } - - #[test] - fn test_product() { - let xs: ~[int] = ~[1, 2, 3, 4]; - assert_eq!(do product |f| { xs.iter().advance(f) }, 24); - } - - #[test] - fn test_empty_product() { - let xs: ~[int] = ~[]; - assert_eq!(do product |f| { xs.iter().advance(f) }, 1); - } -} diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index 13d19b276f59..58db740167f3 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -47,7 +47,7 @@ pub use cmp::{Eq, ApproxEq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Great pub use char::Char; pub use container::{Container, Mutable, Map, Set}; pub use hash::Hash; -pub use iter::{Times, FromIter}; +pub use iter::{Times}; pub use iterator::{Iterator, IteratorUtil, OrdIterator}; pub use num::{Num, NumCast}; pub use num::{Orderable, Signed, Unsigned, Round}; diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index cff4ac10145c..bbb7de69c404 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -19,7 +19,6 @@ use cmp; use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater}; use clone::Clone; use iterator::{FromIterator, Iterator, IteratorUtil}; -use iter::FromIter; use kinds::Copy; use libc; use num::Zero; @@ -2311,15 +2310,6 @@ pub struct VecMutRevIterator<'self, T> { } iterator!{impl VecMutRevIterator -> &'self mut T, -1} -impl FromIter for ~[T]{ - #[inline] - pub fn from_iter(iter: &fn(f: &fn(T) -> bool) -> bool) -> ~[T] { - let mut v = ~[]; - for iter |x| { v.push(x) } - v - } -} - #[cfg(stage0)] impl> FromIterator for ~[A] { pub fn from_iterator(iterator: &mut T) -> ~[A] { From 652dc73b4db157f46c4a022be7f2fdcf81f3ad56 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Sun, 30 Jun 2013 17:34:23 -0700 Subject: [PATCH 07/93] extra: docs, tests and new functionality for the extra::stats module --- src/libextra/stats.rs | 852 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 832 insertions(+), 20 deletions(-) diff --git a/src/libextra/stats.rs b/src/libextra/stats.rs index 8351e4db6b8c..0271b393f611 100644 --- a/src/libextra/stats.rs +++ b/src/libextra/stats.rs @@ -8,32 +8,135 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[allow(missing_doc)]; - - -use std::f64; -use std::cmp; -use std::num; -use std::vec; use sort; +use std::cmp; +use std::io; +use std::num; +use std::f64; +use std::vec; // NB: this can probably be rewritten in terms of num::Num // to be less f64-specific. +/// Trait that provides simple descriptive statistics on a univariate set of numeric samples. pub trait Stats { + + /// Sum of the samples. fn sum(self) -> f64; + + /// Minimum value of the samples. fn min(self) -> f64; + + /// Maximum value of the samples. fn max(self) -> f64; + + /// Arithmetic mean (average) of the samples: sum divided by sample-count. + /// + /// See: https://en.wikipedia.org/wiki/Arithmetic_mean fn mean(self) -> f64; + + /// Median of the samples: value separating the lower half of the samples from the higher half. + /// Equal to `self.percentile(50.0)`. + /// + /// See: https://en.wikipedia.org/wiki/Median fn median(self) -> f64; + + /// Variance of the samples: bias-corrected mean of the squares of the differences of each + /// sample from the sample mean. Note that this calculates the _sample variance_ rather than the + /// population variance, which is assumed to be unknown. It therefore corrects the `(n-1)/n` + /// bias that would appear if we calculated a population variance, by dividing by `(n-1)` rather + /// than `n`. + /// + /// See: https://en.wikipedia.org/wiki/Variance fn var(self) -> f64; + + /// Standard deviation: the square root of the sample variance. + /// + /// Note: this is not a robust statistic for non-normal distributions. Prefer the + /// `median_abs_dev` for unknown distributions. + /// + /// See: https://en.wikipedia.org/wiki/Standard_deviation fn std_dev(self) -> f64; + + /// Standard deviation as a percent of the mean value. See `std_dev` and `mean`. + /// + /// Note: this is not a robust statistic for non-normal distributions. Prefer the + /// `median_abs_dev_pct` for unknown distributions. fn std_dev_pct(self) -> f64; + + /// Scaled median of the absolute deviations of each sample from the sample median. This is a + /// robust (distribution-agnostic) estimator of sample variability. Use this in preference to + /// `std_dev` if you cannot assume your sample is normally distributed. Note that this is scaled + /// by the constant `1.4826` to allow its use as a consistent estimator for the standard + /// deviation. + /// + /// See: http://en.wikipedia.org/wiki/Median_absolute_deviation fn median_abs_dev(self) -> f64; + + /// Median absolute deviation as a percent of the median. See `median_abs_dev` and `median`. fn median_abs_dev_pct(self) -> f64; + + /// Percentile: the value below which `pct` percent of the values in `self` fall. For example, + /// percentile(95.0) will return the value `v` such that that 95% of the samples `s` in `self` + /// satisfy `s <= v`. + /// + /// Calculated by linear interpolation between closest ranks. + /// + /// See: http://en.wikipedia.org/wiki/Percentile + fn percentile(self, pct: f64) -> f64; + + /// Quartiles of the sample: three values that divide the sample into four equal groups, each + /// with 1/4 of the data. The middle value is the median. See `median` and `percentile`. This + /// function may calculate the 3 quartiles more efficiently than 3 calls to `percentile`, but + /// is otherwise equivalent. + /// + /// See also: https://en.wikipedia.org/wiki/Quartile + fn quartiles(self) -> (f64,f64,f64); + + /// Inter-quartile range: the difference between the 25th percentile (1st quartile) and the 75th + /// percentile (3rd quartile). See `quartiles`. + /// + /// See also: https://en.wikipedia.org/wiki/Interquartile_range + fn iqr(self) -> f64; +} + +/// Extracted collection of all the summary statistics of a sample set. +struct Summary { + sum: f64, + min: f64, + max: f64, + mean: f64, + median: f64, + var: f64, + std_dev: f64, + std_dev_pct: f64, + median_abs_dev: f64, + median_abs_dev_pct: f64, + quartiles: (f64,f64,f64), + iqr: f64, +} + +impl Summary { + fn new(samples: &[f64]) -> Summary { + Summary { + sum: samples.sum(), + min: samples.min(), + max: samples.max(), + mean: samples.mean(), + median: samples.median(), + var: samples.var(), + std_dev: samples.std_dev(), + std_dev_pct: samples.std_dev_pct(), + median_abs_dev: samples.median_abs_dev(), + median_abs_dev_pct: samples.median_abs_dev_pct(), + quartiles: samples.quartiles(), + iqr: samples.iqr() + } + } } impl<'self> Stats for &'self [f64] { + fn sum(self) -> f64 { self.iter().fold(0.0, |p,q| p + *q) } @@ -54,19 +157,11 @@ impl<'self> Stats for &'self [f64] { } fn median(self) -> f64 { - assert!(self.len() != 0); - let mut tmp = vec::to_owned(self); - sort::tim_sort(tmp); - if tmp.len() & 1 == 0 { - let m = tmp.len() / 2; - (tmp[m] + tmp[m-1]) / 2.0 - } else { - tmp[tmp.len() / 2] - } + self.percentile(50.0) } fn var(self) -> f64 { - if self.len() == 0 { + if self.len() < 2 { 0.0 } else { let mean = self.mean(); @@ -75,7 +170,10 @@ impl<'self> Stats for &'self [f64] { let x = *s - mean; v += x*x; } - v/(self.len() as f64) + // NB: this is _supposed to be_ len-1, not len. If you + // change it back to len, you will be calculating a + // population variance, not a sample variance. + v/((self.len()-1) as f64) } } @@ -89,11 +187,725 @@ impl<'self> Stats for &'self [f64] { fn median_abs_dev(self) -> f64 { let med = self.median(); - let abs_devs = self.map(|v| num::abs(med - *v)); - abs_devs.median() + let abs_devs = self.map(|&v| num::abs(med - v)); + // This constant is derived by smarter statistics brains than me, but it is + // consistent with how R and other packages treat the MAD. + abs_devs.median() * 1.4826 } fn median_abs_dev_pct(self) -> f64 { (self.median_abs_dev() / self.median()) * 100.0 } + + fn percentile(self, pct: f64) -> f64 { + let mut tmp = vec::to_owned(self); + sort::tim_sort(tmp); + percentile_of_sorted(tmp, pct) + } + + fn quartiles(self) -> (f64,f64,f64) { + let mut tmp = vec::to_owned(self); + sort::tim_sort(tmp); + let a = percentile_of_sorted(tmp, 25.0); + let b = percentile_of_sorted(tmp, 50.0); + let c = percentile_of_sorted(tmp, 75.0); + (a,b,c) + } + + fn iqr(self) -> f64 { + let (a,_,c) = self.quartiles(); + c - a + } +} + + +// Helper function: extract a value representing the `pct` percentile of a sorted sample-set, using +// linear interpolation. If samples are not sorted, return nonsensical value. +priv fn percentile_of_sorted(sorted_samples: &[f64], + pct: f64) -> f64 { + assert!(sorted_samples.len() != 0); + if sorted_samples.len() == 1 { + return sorted_samples[0]; + } + assert!(0.0 <= pct); + assert!(pct <= 100.0); + if pct == 100.0 { + return sorted_samples[sorted_samples.len() - 1]; + } + let rank = (pct / 100.0) * ((sorted_samples.len() - 1) as f64); + let lrank = rank.floor(); + let d = rank - lrank; + let n = lrank as uint; + let lo = sorted_samples[n]; + let hi = sorted_samples[n+1]; + lo + (hi - lo) * d +} + + +/// Winsorize a set of samples, replacing values above the `100-pct` percentile and below the `pct` +/// percentile with those percentiles themselves. This is a way of minimizing the effect of +/// outliers, at the cost of biasing the sample. It differs from trimming in that it does not +/// change the number of samples, just changes the values of those that are outliers. +/// +/// See: http://en.wikipedia.org/wiki/Winsorising +pub fn winsorize(samples: &mut [f64], pct: f64) { + let mut tmp = vec::to_owned(samples); + sort::tim_sort(tmp); + let lo = percentile_of_sorted(tmp, pct); + let hi = percentile_of_sorted(tmp, 100.0-pct); + for samples.mut_iter().advance |samp| { + if *samp > hi { + *samp = hi + } else if *samp < lo { + *samp = lo + } + } +} + +/// Render writes the min, max and quartiles of the provided `Summary` to the provided `Writer`. +pub fn write_5_number_summary(w: @io::Writer, s: &Summary) { + let (q1,q2,q3) = s.quartiles; + w.write_str(fmt!("(min=%f, q1=%f, med=%f, q3=%f, max=%f)", + s.min as float, + q1 as float, + q2 as float, + q3 as float, + s.max as float)); +} + +/// Render a boxplot to the provided writer. The boxplot shows the min, max and quartiles of the +/// provided `Summary` (thus includes the mean) and is scaled to display within the range of the +/// nearest multiple-of-a-power-of-ten above and below the min and max of possible values, and +/// target `width_hint` characters of display (though it will be wider if necessary). +/// +/// As an example, the summary with 5-number-summary `(min=15, q1=17, med=20, q3=24, max=31)` might +/// display as: +/// +/// ~~~~ +/// 10 | [--****#******----------] | 40 +/// ~~~~ + +pub fn write_boxplot(w: @io::Writer, s: &Summary, width_hint: uint) { + + let (q1,q2,q3) = s.quartiles; + + let lomag = (10.0_f64).pow(&s.min.log10().floor()); + let himag = (10.0_f64).pow(&(s.max.log10().floor())); + let lo = (s.min / lomag).floor() * lomag; + let hi = (s.max / himag).ceil() * himag; + + let range = hi - lo; + + let lostr = lo.to_str(); + let histr = hi.to_str(); + + let overhead_width = lostr.len() + histr.len() + 4; + let range_width = width_hint - overhead_width;; + let char_step = range / (range_width as f64); + + w.write_str(lostr); + w.write_char(' '); + w.write_char('|'); + + let mut c = 0; + let mut v = lo; + + while c < range_width && v < s.min { + w.write_char(' '); + v += char_step; + c += 1; + } + w.write_char('['); + c += 1; + while c < range_width && v < q1 { + w.write_char('-'); + v += char_step; + c += 1; + } + while c < range_width && v < q2 { + w.write_char('*'); + v += char_step; + c += 1; + } + w.write_char('#'); + c += 1; + while c < range_width && v < q3 { + w.write_char('*'); + v += char_step; + c += 1; + } + while c < range_width && v < s.max { + w.write_char('-'); + v += char_step; + c += 1; + } + w.write_char(']'); + while c < range_width { + w.write_char(' '); + v += char_step; + c += 1; + } + + w.write_char('|'); + w.write_char(' '); + w.write_str(histr); +} + +// Test vectors generated from R, using the script src/etc/stat-test-vectors.r. + +#[cfg(test)] +mod tests { + + use stats::Stats; + use stats::Summary; + use stats::write_5_number_summary; + use stats::write_boxplot; + use std::io; + + fn check(samples: &[f64], summ: &Summary) { + + let summ2 = Summary::new(samples); + + let w = io::stdout(); + w.write_char('\n'); + write_5_number_summary(w, &summ2); + w.write_char('\n'); + write_boxplot(w, &summ2, 50); + w.write_char('\n'); + + assert_eq!(summ.sum, summ2.sum); + assert_eq!(summ.min, summ2.min); + assert_eq!(summ.max, summ2.max); + assert_eq!(summ.mean, summ2.mean); + assert_eq!(summ.median, summ2.median); + + // We needed a few more digits to get exact equality on these + // but they're within float epsilon, which is 1.0e-6. + assert_approx_eq!(summ.var, summ2.var); + assert_approx_eq!(summ.std_dev, summ2.std_dev); + assert_approx_eq!(summ.std_dev_pct, summ2.std_dev_pct); + assert_approx_eq!(summ.median_abs_dev, summ2.median_abs_dev); + assert_approx_eq!(summ.median_abs_dev_pct, summ2.median_abs_dev_pct); + + assert_eq!(summ.quartiles, summ2.quartiles); + assert_eq!(summ.iqr, summ2.iqr); + } + + #[test] + fn test_norm2() { + let val = &[ + 958.0000000000, + 924.0000000000, + ]; + let summ = &Summary { + sum: 1882.0000000000, + min: 924.0000000000, + max: 958.0000000000, + mean: 941.0000000000, + median: 941.0000000000, + var: 578.0000000000, + std_dev: 24.0416305603, + std_dev_pct: 2.5549022912, + median_abs_dev: 25.2042000000, + median_abs_dev_pct: 2.6784484591, + quartiles: (932.5000000000,941.0000000000,949.5000000000), + iqr: 17.0000000000, + }; + check(val, summ); + } + #[test] + fn test_norm10narrow() { + let val = &[ + 966.0000000000, + 985.0000000000, + 1110.0000000000, + 848.0000000000, + 821.0000000000, + 975.0000000000, + 962.0000000000, + 1157.0000000000, + 1217.0000000000, + 955.0000000000, + ]; + let summ = &Summary { + sum: 9996.0000000000, + min: 821.0000000000, + max: 1217.0000000000, + mean: 999.6000000000, + median: 970.5000000000, + var: 16050.7111111111, + std_dev: 126.6914010938, + std_dev_pct: 12.6742097933, + median_abs_dev: 102.2994000000, + median_abs_dev_pct: 10.5408964451, + quartiles: (956.7500000000,970.5000000000,1078.7500000000), + iqr: 122.0000000000, + }; + check(val, summ); + } + #[test] + fn test_norm10medium() { + let val = &[ + 954.0000000000, + 1064.0000000000, + 855.0000000000, + 1000.0000000000, + 743.0000000000, + 1084.0000000000, + 704.0000000000, + 1023.0000000000, + 357.0000000000, + 869.0000000000, + ]; + let summ = &Summary { + sum: 8653.0000000000, + min: 357.0000000000, + max: 1084.0000000000, + mean: 865.3000000000, + median: 911.5000000000, + var: 48628.4555555556, + std_dev: 220.5186059170, + std_dev_pct: 25.4846418487, + median_abs_dev: 195.7032000000, + median_abs_dev_pct: 21.4704552935, + quartiles: (771.0000000000,911.5000000000,1017.2500000000), + iqr: 246.2500000000, + }; + check(val, summ); + } + #[test] + fn test_norm10wide() { + let val = &[ + 505.0000000000, + 497.0000000000, + 1591.0000000000, + 887.0000000000, + 1026.0000000000, + 136.0000000000, + 1580.0000000000, + 940.0000000000, + 754.0000000000, + 1433.0000000000, + ]; + let summ = &Summary { + sum: 9349.0000000000, + min: 136.0000000000, + max: 1591.0000000000, + mean: 934.9000000000, + median: 913.5000000000, + var: 239208.9888888889, + std_dev: 489.0899599142, + std_dev_pct: 52.3146817750, + median_abs_dev: 611.5725000000, + median_abs_dev_pct: 66.9482758621, + quartiles: (567.2500000000,913.5000000000,1331.2500000000), + iqr: 764.0000000000, + }; + check(val, summ); + } + #[test] + fn test_norm25verynarrow() { + let val = &[ + 991.0000000000, + 1018.0000000000, + 998.0000000000, + 1013.0000000000, + 974.0000000000, + 1007.0000000000, + 1014.0000000000, + 999.0000000000, + 1011.0000000000, + 978.0000000000, + 985.0000000000, + 999.0000000000, + 983.0000000000, + 982.0000000000, + 1015.0000000000, + 1002.0000000000, + 977.0000000000, + 948.0000000000, + 1040.0000000000, + 974.0000000000, + 996.0000000000, + 989.0000000000, + 1015.0000000000, + 994.0000000000, + 1024.0000000000, + ]; + let summ = &Summary { + sum: 24926.0000000000, + min: 948.0000000000, + max: 1040.0000000000, + mean: 997.0400000000, + median: 998.0000000000, + var: 393.2066666667, + std_dev: 19.8294393937, + std_dev_pct: 1.9888308788, + median_abs_dev: 22.2390000000, + median_abs_dev_pct: 2.2283567134, + quartiles: (983.0000000000,998.0000000000,1013.0000000000), + iqr: 30.0000000000, + }; + check(val, summ); + } + #[test] + fn test_exp10a() { + let val = &[ + 23.0000000000, + 11.0000000000, + 2.0000000000, + 57.0000000000, + 4.0000000000, + 12.0000000000, + 5.0000000000, + 29.0000000000, + 3.0000000000, + 21.0000000000, + ]; + let summ = &Summary { + sum: 167.0000000000, + min: 2.0000000000, + max: 57.0000000000, + mean: 16.7000000000, + median: 11.5000000000, + var: 287.7888888889, + std_dev: 16.9643416875, + std_dev_pct: 101.5828843560, + median_abs_dev: 13.3434000000, + median_abs_dev_pct: 116.0295652174, + quartiles: (4.2500000000,11.5000000000,22.5000000000), + iqr: 18.2500000000, + }; + check(val, summ); + } + #[test] + fn test_exp10b() { + let val = &[ + 24.0000000000, + 17.0000000000, + 6.0000000000, + 38.0000000000, + 25.0000000000, + 7.0000000000, + 51.0000000000, + 2.0000000000, + 61.0000000000, + 32.0000000000, + ]; + let summ = &Summary { + sum: 263.0000000000, + min: 2.0000000000, + max: 61.0000000000, + mean: 26.3000000000, + median: 24.5000000000, + var: 383.5666666667, + std_dev: 19.5848580967, + std_dev_pct: 74.4671410520, + median_abs_dev: 22.9803000000, + median_abs_dev_pct: 93.7971428571, + quartiles: (9.5000000000,24.5000000000,36.5000000000), + iqr: 27.0000000000, + }; + check(val, summ); + } + #[test] + fn test_exp10c() { + let val = &[ + 71.0000000000, + 2.0000000000, + 32.0000000000, + 1.0000000000, + 6.0000000000, + 28.0000000000, + 13.0000000000, + 37.0000000000, + 16.0000000000, + 36.0000000000, + ]; + let summ = &Summary { + sum: 242.0000000000, + min: 1.0000000000, + max: 71.0000000000, + mean: 24.2000000000, + median: 22.0000000000, + var: 458.1777777778, + std_dev: 21.4050876611, + std_dev_pct: 88.4507754589, + median_abs_dev: 21.4977000000, + median_abs_dev_pct: 97.7168181818, + quartiles: (7.7500000000,22.0000000000,35.0000000000), + iqr: 27.2500000000, + }; + check(val, summ); + } + #[test] + fn test_exp25() { + let val = &[ + 3.0000000000, + 24.0000000000, + 1.0000000000, + 19.0000000000, + 7.0000000000, + 5.0000000000, + 30.0000000000, + 39.0000000000, + 31.0000000000, + 13.0000000000, + 25.0000000000, + 48.0000000000, + 1.0000000000, + 6.0000000000, + 42.0000000000, + 63.0000000000, + 2.0000000000, + 12.0000000000, + 108.0000000000, + 26.0000000000, + 1.0000000000, + 7.0000000000, + 44.0000000000, + 25.0000000000, + 11.0000000000, + ]; + let summ = &Summary { + sum: 593.0000000000, + min: 1.0000000000, + max: 108.0000000000, + mean: 23.7200000000, + median: 19.0000000000, + var: 601.0433333333, + std_dev: 24.5161851301, + std_dev_pct: 103.3565983562, + median_abs_dev: 19.2738000000, + median_abs_dev_pct: 101.4410526316, + quartiles: (6.0000000000,19.0000000000,31.0000000000), + iqr: 25.0000000000, + }; + check(val, summ); + } + #[test] + fn test_binom25() { + let val = &[ + 18.0000000000, + 17.0000000000, + 27.0000000000, + 15.0000000000, + 21.0000000000, + 25.0000000000, + 17.0000000000, + 24.0000000000, + 25.0000000000, + 24.0000000000, + 26.0000000000, + 26.0000000000, + 23.0000000000, + 15.0000000000, + 23.0000000000, + 17.0000000000, + 18.0000000000, + 18.0000000000, + 21.0000000000, + 16.0000000000, + 15.0000000000, + 31.0000000000, + 20.0000000000, + 17.0000000000, + 15.0000000000, + ]; + let summ = &Summary { + sum: 514.0000000000, + min: 15.0000000000, + max: 31.0000000000, + mean: 20.5600000000, + median: 20.0000000000, + var: 20.8400000000, + std_dev: 4.5650848842, + std_dev_pct: 22.2037202539, + median_abs_dev: 5.9304000000, + median_abs_dev_pct: 29.6520000000, + quartiles: (17.0000000000,20.0000000000,24.0000000000), + iqr: 7.0000000000, + }; + check(val, summ); + } + #[test] + fn test_pois25lambda30() { + let val = &[ + 27.0000000000, + 33.0000000000, + 34.0000000000, + 34.0000000000, + 24.0000000000, + 39.0000000000, + 28.0000000000, + 27.0000000000, + 31.0000000000, + 28.0000000000, + 38.0000000000, + 21.0000000000, + 33.0000000000, + 36.0000000000, + 29.0000000000, + 37.0000000000, + 32.0000000000, + 34.0000000000, + 31.0000000000, + 39.0000000000, + 25.0000000000, + 31.0000000000, + 32.0000000000, + 40.0000000000, + 24.0000000000, + ]; + let summ = &Summary { + sum: 787.0000000000, + min: 21.0000000000, + max: 40.0000000000, + mean: 31.4800000000, + median: 32.0000000000, + var: 26.5933333333, + std_dev: 5.1568724372, + std_dev_pct: 16.3814245145, + median_abs_dev: 5.9304000000, + median_abs_dev_pct: 18.5325000000, + quartiles: (28.0000000000,32.0000000000,34.0000000000), + iqr: 6.0000000000, + }; + check(val, summ); + } + #[test] + fn test_pois25lambda40() { + let val = &[ + 42.0000000000, + 50.0000000000, + 42.0000000000, + 46.0000000000, + 34.0000000000, + 45.0000000000, + 34.0000000000, + 49.0000000000, + 39.0000000000, + 28.0000000000, + 40.0000000000, + 35.0000000000, + 37.0000000000, + 39.0000000000, + 46.0000000000, + 44.0000000000, + 32.0000000000, + 45.0000000000, + 42.0000000000, + 37.0000000000, + 48.0000000000, + 42.0000000000, + 33.0000000000, + 42.0000000000, + 48.0000000000, + ]; + let summ = &Summary { + sum: 1019.0000000000, + min: 28.0000000000, + max: 50.0000000000, + mean: 40.7600000000, + median: 42.0000000000, + var: 34.4400000000, + std_dev: 5.8685603004, + std_dev_pct: 14.3978417577, + median_abs_dev: 5.9304000000, + median_abs_dev_pct: 14.1200000000, + quartiles: (37.0000000000,42.0000000000,45.0000000000), + iqr: 8.0000000000, + }; + check(val, summ); + } + #[test] + fn test_pois25lambda50() { + let val = &[ + 45.0000000000, + 43.0000000000, + 44.0000000000, + 61.0000000000, + 51.0000000000, + 53.0000000000, + 59.0000000000, + 52.0000000000, + 49.0000000000, + 51.0000000000, + 51.0000000000, + 50.0000000000, + 49.0000000000, + 56.0000000000, + 42.0000000000, + 52.0000000000, + 51.0000000000, + 43.0000000000, + 48.0000000000, + 48.0000000000, + 50.0000000000, + 42.0000000000, + 43.0000000000, + 42.0000000000, + 60.0000000000, + ]; + let summ = &Summary { + sum: 1235.0000000000, + min: 42.0000000000, + max: 61.0000000000, + mean: 49.4000000000, + median: 50.0000000000, + var: 31.6666666667, + std_dev: 5.6273143387, + std_dev_pct: 11.3913245723, + median_abs_dev: 4.4478000000, + median_abs_dev_pct: 8.8956000000, + quartiles: (44.0000000000,50.0000000000,52.0000000000), + iqr: 8.0000000000, + }; + check(val, summ); + } + #[test] + fn test_unif25() { + let val = &[ + 99.0000000000, + 55.0000000000, + 92.0000000000, + 79.0000000000, + 14.0000000000, + 2.0000000000, + 33.0000000000, + 49.0000000000, + 3.0000000000, + 32.0000000000, + 84.0000000000, + 59.0000000000, + 22.0000000000, + 86.0000000000, + 76.0000000000, + 31.0000000000, + 29.0000000000, + 11.0000000000, + 41.0000000000, + 53.0000000000, + 45.0000000000, + 44.0000000000, + 98.0000000000, + 98.0000000000, + 7.0000000000, + ]; + let summ = &Summary { + sum: 1242.0000000000, + min: 2.0000000000, + max: 99.0000000000, + mean: 49.6800000000, + median: 45.0000000000, + var: 1015.6433333333, + std_dev: 31.8691595957, + std_dev_pct: 64.1488719719, + median_abs_dev: 45.9606000000, + median_abs_dev_pct: 102.1346666667, + quartiles: (29.0000000000,45.0000000000,79.0000000000), + iqr: 50.0000000000, + }; + check(val, summ); + } } From fd192891085ecb3c4fee458b2dc374aa5d1ed18d Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Mon, 1 Jul 2013 13:02:14 +0900 Subject: [PATCH 08/93] Classify newtype structs S(T) as immediates if T is an immediate --- src/librustc/middle/trans/base.rs | 12 +++++----- src/librustc/middle/trans/callee.rs | 10 ++++---- src/librustc/middle/trans/datum.rs | 29 +++++++---------------- src/librustc/middle/trans/expr.rs | 2 +- src/librustc/middle/trans/foreign.rs | 15 ++++++------ src/librustc/middle/trans/monomorphize.rs | 2 +- src/librustc/middle/trans/type_of.rs | 6 ++--- src/librustc/middle/ty.rs | 19 ++++++++++++--- 8 files changed, 48 insertions(+), 47 deletions(-) diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index cf671bdce677..3939bbaa488e 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -996,13 +996,13 @@ pub fn do_spill_noroot(cx: block, v: ValueRef) -> ValueRef { pub fn spill_if_immediate(cx: block, v: ValueRef, t: ty::t) -> ValueRef { let _icx = push_ctxt("spill_if_immediate"); - if ty::type_is_immediate(t) { return do_spill(cx, v, t); } + if ty::type_is_immediate(cx.tcx(), t) { return do_spill(cx, v, t); } return v; } pub fn load_if_immediate(cx: block, v: ValueRef, t: ty::t) -> ValueRef { let _icx = push_ctxt("load_if_immediate"); - if ty::type_is_immediate(t) { return Load(cx, v); } + if ty::type_is_immediate(cx.tcx(), t) { return Load(cx, v); } return v; } @@ -1527,7 +1527,7 @@ pub fn mk_standard_basic_blocks(llfn: ValueRef) -> BasicBlocks { // slot where the return value of the function must go. pub fn make_return_pointer(fcx: fn_ctxt, output_type: ty::t) -> ValueRef { unsafe { - if !ty::type_is_immediate(output_type) { + if !ty::type_is_immediate(fcx.ccx.tcx, output_type) { llvm::LLVMGetParam(fcx.llfn, 0) } else { let lloutputtype = type_of::type_of(fcx.ccx, output_type); @@ -1566,7 +1566,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext, ty::subst_tps(ccx.tcx, substs.tys, substs.self_ty, output_type) } }; - let is_immediate = ty::type_is_immediate(substd_output_type); + let is_immediate = ty::type_is_immediate(ccx.tcx, substd_output_type); let fcx = @mut fn_ctxt_ { llfn: llfndecl, llenv: unsafe { @@ -1672,7 +1672,7 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt, match fcx.llself { Some(slf) => { let self_val = if slf.is_copy - && datum::appropriate_mode(slf.t).is_by_value() { + && datum::appropriate_mode(bcx.tcx(), slf.t).is_by_value() { let tmp = BitCast(bcx, slf.v, type_of(bcx.ccx(), slf.t)); let alloc = alloc_ty(bcx, slf.t); Store(bcx, tmp, alloc); @@ -1700,7 +1700,7 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt, // This alloca should be optimized away by LLVM's mem-to-reg pass in // the event it's not truly needed. // only by value if immediate: - let llarg = if datum::appropriate_mode(arg_ty).is_by_value() { + let llarg = if datum::appropriate_mode(bcx.tcx(), arg_ty).is_by_value() { let alloc = alloc_ty(bcx, arg_ty); Store(bcx, raw_llarg, alloc); alloc diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 41f1d0e61e53..05fe0bed3b69 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -633,7 +633,7 @@ pub fn trans_call_inner(in_cx: block, let mut llargs = ~[]; - if !ty::type_is_immediate(ret_ty) { + if !ty::type_is_immediate(bcx.tcx(), ret_ty) { llargs.push(llretslot); } @@ -680,7 +680,7 @@ pub fn trans_call_inner(in_cx: block, // case to ignore instead of invoking the Store // below into a scratch pointer of a mismatched // type. - } else if ty::type_is_immediate(ret_ty) { + } else if ty::type_is_immediate(bcx.tcx(), ret_ty) { let llscratchptr = alloc_ty(bcx, ret_ty); Store(bcx, llresult, llscratchptr); bcx = glue::drop_ty(bcx, llscratchptr, ret_ty); @@ -694,7 +694,7 @@ pub fn trans_call_inner(in_cx: block, // If this is an immediate, store into the result location. // (If this was not an immediate, the result will already be // directly written into the output slot.) - if ty::type_is_immediate(ret_ty) { + if ty::type_is_immediate(bcx.tcx(), ret_ty) { Store(bcx, llresult, lldest); } } @@ -898,7 +898,7 @@ pub fn trans_arg_expr(bcx: block, } ty::ByCopy => { if ty::type_needs_drop(bcx.tcx(), arg_datum.ty) || - arg_datum.appropriate_mode().is_by_ref() { + arg_datum.appropriate_mode(bcx.tcx()).is_by_ref() { debug!("by copy arg with type %s, storing to scratch", bcx.ty_to_str(arg_datum.ty)); let scratch = scratch_datum(bcx, arg_datum.ty, false); @@ -914,7 +914,7 @@ pub fn trans_arg_expr(bcx: block, scratch.add_clean(bcx); temp_cleanups.push(scratch.val); - match scratch.appropriate_mode() { + match scratch.appropriate_mode(bcx.tcx()) { ByValue => val = Load(bcx, scratch.val), ByRef(_) => val = scratch.val, } diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs index 0fe3dfe80c8c..b9829fd47c1a 100644 --- a/src/librustc/middle/trans/datum.rs +++ b/src/librustc/middle/trans/datum.rs @@ -188,7 +188,7 @@ pub fn scratch_datum(bcx: block, ty: ty::t, zero: bool) -> Datum { Datum { val: scratch, ty: ty, mode: ByRef(RevokeClean) } } -pub fn appropriate_mode(ty: ty::t) -> DatumMode { +pub fn appropriate_mode(tcx: ty::ctxt, ty: ty::t) -> DatumMode { /*! * * Indicates the "appropriate" mode for this value, @@ -197,7 +197,7 @@ pub fn appropriate_mode(ty: ty::t) -> DatumMode { if ty::type_is_nil(ty) || ty::type_is_bot(ty) { ByValue - } else if ty::type_is_immediate(ty) { + } else if ty::type_is_immediate(tcx, ty) { ByValue } else { ByRef(RevokeClean) @@ -508,10 +508,10 @@ impl Datum { } } - pub fn appropriate_mode(&self) -> DatumMode { + pub fn appropriate_mode(&self, tcx: ty::ctxt) -> DatumMode { /*! See the `appropriate_mode()` function */ - appropriate_mode(self.ty) + appropriate_mode(tcx, self.ty) } pub fn to_appropriate_llval(&self, bcx: block) -> ValueRef { @@ -519,7 +519,7 @@ impl Datum { * * Yields an llvalue with the `appropriate_mode()`. */ - match self.appropriate_mode() { + match self.appropriate_mode(bcx.tcx()) { ByValue => self.to_value_llval(bcx), ByRef(_) => self.to_ref_llval(bcx) } @@ -530,7 +530,7 @@ impl Datum { * * Yields a datum with the `appropriate_mode()`. */ - match self.appropriate_mode() { + match self.appropriate_mode(bcx.tcx()) { ByValue => self.to_value_datum(bcx), ByRef(_) => self.to_ref_datum(bcx) } @@ -657,13 +657,7 @@ impl Datum { ByValue => { // Actually, this case cannot happen right // now, because enums are never immediate. - // But in principle newtype'd immediate - // values should be immediate, and in that - // case the * would be a no-op except for - // changing the type, so I am putting this - // code in place here to do the right - // thing if this change ever goes through. - assert!(ty::type_is_immediate(ty)); + assert!(ty::type_is_immediate(bcx.tcx(), ty)); (Some(Datum {ty: ty, ..*self}), bcx) } }; @@ -695,14 +689,7 @@ impl Datum { ) } ByValue => { - // Actually, this case cannot happen right now, - // because structs are never immediate. But in - // principle, newtype'd immediate values should be - // immediate, and in that case the * would be a no-op - // except for changing the type, so I am putting this - // code in place here to do the right thing if this - // change ever goes through. - assert!(ty::type_is_immediate(ty)); + assert!(ty::type_is_immediate(bcx.tcx(), ty)); (Some(Datum {ty: ty, ..*self}), bcx) } } diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 1511f2541407..d07c2b736c47 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -291,7 +291,7 @@ pub fn trans_to_datum(bcx: block, expr: @ast::expr) -> DatumBlock { debug!("add_env(closure_ty=%s)", closure_ty.repr(tcx)); let scratch = scratch_datum(bcx, closure_ty, false); let llfn = GEPi(bcx, scratch.val, [0u, abi::fn_field_code]); - assert_eq!(datum.appropriate_mode(), ByValue); + assert_eq!(datum.appropriate_mode(tcx), ByValue); Store(bcx, datum.to_appropriate_llval(bcx), llfn); let llenv = GEPi(bcx, scratch.val, [0u, abi::fn_field_box]); Store(bcx, base::null_env_ptr(bcx), llenv); diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index c01f01db5fd1..76dc7e113814 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -103,7 +103,7 @@ fn foreign_signature(ccx: &mut CrateContext, fn_sig: &ty::FnSig) LlvmSignature { llarg_tys: llarg_tys, llret_ty: llret_ty, - sret: !ty::type_is_immediate(fn_sig.output), + sret: !ty::type_is_immediate(ccx.tcx, fn_sig.output), } } @@ -192,7 +192,7 @@ fn build_wrap_fn_(ccx: @mut CrateContext, // Patch up the return type if it's not immediate and we're returning via // the C ABI. - if needs_c_return && !ty::type_is_immediate(tys.fn_sig.output) { + if needs_c_return && !ty::type_is_immediate(ccx.tcx, tys.fn_sig.output) { let lloutputtype = type_of::type_of(fcx.ccx, tys.fn_sig.output); fcx.llretptr = Some(alloca(raw_block(fcx, false, fcx.llstaticallocas), lloutputtype)); @@ -648,7 +648,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, // intrinsics, there are no argument cleanups to // concern ourselves with. let tp_ty = substs.tys[0]; - let mode = appropriate_mode(tp_ty); + let mode = appropriate_mode(ccx.tcx, tp_ty); let src = Datum {val: get_param(decl, first_real_arg + 1u), ty: tp_ty, mode: mode}; bcx = src.move_to(bcx, DROP_EXISTING, @@ -657,7 +657,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, "move_val_init" => { // See comments for `"move_val"`. let tp_ty = substs.tys[0]; - let mode = appropriate_mode(tp_ty); + let mode = appropriate_mode(ccx.tcx, tp_ty); let src = Datum {val: get_param(decl, first_real_arg + 1u), ty: tp_ty, mode: mode}; bcx = src.move_to(bcx, INIT, get_param(decl, first_real_arg)); @@ -731,7 +731,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let lldestptr = PointerCast(bcx, lldestptr, Type::i8p()); let llsrcval = get_param(decl, first_real_arg); - let llsrcptr = if ty::type_is_immediate(in_type) { + let llsrcptr = if ty::type_is_immediate(ccx.tcx, in_type) { let llsrcptr = alloca(bcx, llintype); Store(bcx, llsrcval, llsrcptr); llsrcptr @@ -1221,7 +1221,7 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext, let mut i = 0u; let n = tys.fn_sig.inputs.len(); - if !ty::type_is_immediate(tys.fn_sig.output) { + if !ty::type_is_immediate(bcx.tcx(), tys.fn_sig.output) { let llretptr = load_inbounds(bcx, llargbundle, [0u, n]); llargvals.push(llretptr); } @@ -1247,7 +1247,8 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext, shim_types: &ShimTypes, llargbundle: ValueRef, llretval: ValueRef) { - if bcx.fcx.llretptr.is_some() && ty::type_is_immediate(shim_types.fn_sig.output) { + if bcx.fcx.llretptr.is_some() && + ty::type_is_immediate(bcx.tcx(), shim_types.fn_sig.output) { // Write the value into the argument bundle. let arg_count = shim_types.fn_sig.inputs.len(); let llretptr = load_inbounds(bcx, diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index 4ae8554d7143..51943b9aad9f 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -357,7 +357,7 @@ pub fn make_mono_id(ccx: @mut CrateContext, let llty = type_of::type_of(ccx, subst); let size = machine::llbitsize_of_real(ccx, llty); let align = machine::llalign_of_min(ccx, llty); - let mode = datum::appropriate_mode(subst); + let mode = datum::appropriate_mode(ccx.tcx, subst); let data_class = mono_data_classify(subst); debug!("make_mono_id: type %s -> size %u align %u mode %? class %?", diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index 481f08ee192d..562a8fd69b62 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -18,8 +18,8 @@ use middle::trans::type_::Type; use syntax::ast; -pub fn arg_is_indirect(_: &CrateContext, arg_ty: &ty::t) -> bool { - !ty::type_is_immediate(*arg_ty) +pub fn arg_is_indirect(ccx: &CrateContext, arg_ty: &ty::t) -> bool { + !ty::type_is_immediate(ccx.tcx, *arg_ty) } pub fn type_of_explicit_arg(ccx: &mut CrateContext, arg_ty: &ty::t) -> Type { @@ -41,7 +41,7 @@ pub fn type_of_fn(cx: &mut CrateContext, inputs: &[ty::t], output: ty::t) -> Typ // Arg 0: Output pointer. // (if the output type is non-immediate) - let output_is_immediate = ty::type_is_immediate(output); + let output_is_immediate = ty::type_is_immediate(cx.tcx, output); let lloutputtype = type_of(cx, output); if !output_is_immediate { atys.push(lloutputtype.ptr_to()); diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 4ed21d73f3e7..caf5ff5d1492 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1647,9 +1647,22 @@ pub fn type_is_scalar(ty: t) -> bool { } } -pub fn type_is_immediate(ty: t) -> bool { +fn type_is_newtype_immediate(cx: ctxt, ty: t) -> bool { + match get(ty).sty { + ty_struct(def_id, ref substs) => { + let fields = struct_fields(cx, def_id, substs); + fields.len() == 1 && + fields[0].ident == token::special_idents::unnamed_field && + type_is_immediate(cx, fields[0].mt.ty) + } + _ => false + } +} + +pub fn type_is_immediate(cx: ctxt, ty: t) -> bool { return type_is_scalar(ty) || type_is_boxed(ty) || - type_is_unique(ty) || type_is_region_ptr(ty); + type_is_unique(ty) || type_is_region_ptr(ty) || + type_is_newtype_immediate(cx, ty); } pub fn type_needs_drop(cx: ctxt, ty: t) -> bool { @@ -3148,7 +3161,7 @@ pub fn expr_kind(tcx: ctxt, ast::expr_cast(*) => { match tcx.node_types.find(&(expr.id as uint)) { Some(&t) => { - if ty::type_is_immediate(t) { + if ty::type_is_immediate(tcx, t) { RvalueDatumExpr } else { RvalueDpsExpr From da4384583b84c262dec82be4b041f0332ca16e57 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Mon, 1 Jul 2013 13:50:39 +1000 Subject: [PATCH 09/93] lint: make the non_camel_case_types lint work with scripts without a upper/lowercase distinction. --- src/librustc/middle/lint.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index ce09f790ef45..d7e49a822534 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -854,7 +854,10 @@ fn check_item_non_camel_case_types(cx: &Context, it: &ast::item) { let ident = cx.sess.str_of(ident); assert!(!ident.is_empty()); let ident = ident.trim_chars(&'_'); - char::is_uppercase(ident.char_at(0)) && + + // start with a non-lowercase letter rather than non-uppercase + // ones (some scripts don't have a concept of upper/lowercase) + !ident.char_at(0).is_lowercase() && !ident.contains_char('_') } From c437a16c5d8c00b39dc6c5e36011def997d77224 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Mon, 1 Jul 2013 13:51:13 +1000 Subject: [PATCH 10/93] rustc: add a lint to enforce uppercase statics. --- doc/rust.md | 12 +-- doc/tutorial.md | 4 +- src/compiletest/runtest.rs | 8 +- src/etc/unicode.py | 1 + src/libextra/bitv.rs | 16 ++-- src/libextra/deque.rs | 4 +- src/libextra/ebml.rs | 4 +- src/libextra/flate.rs | 10 +-- src/libextra/num/bigint.rs | 1 + src/libextra/num/complex.rs | 2 + src/libextra/par.rs | 8 +- src/libextra/rope.rs | 32 ++++---- src/libextra/term.rs | 32 ++++---- src/libextra/terminfo/parser/compiled.rs | 2 + src/libextra/test.rs | 14 ++-- src/libextra/time.rs | 8 +- src/librust/rust.rs | 10 +-- src/librustc/middle/lint.rs | 27 ++++++- src/librustc/rustc.rs | 1 + src/librustdoc/demo.rs | 2 +- src/librustdoc/desc_to_brief_pass.rs | 4 +- src/librustpkg/messages.rs | 6 +- src/librustpkg/path_util.rs | 14 ++-- src/librustpkg/rustpkg.rs | 6 +- src/librustpkg/tests.rs | 14 ++-- src/librustpkg/util.rs | 6 +- src/libstd/gc.rs | 1 + src/libstd/libc.rs | 1 + src/libstd/num/cmath.rs | 1 + src/libstd/num/f32.rs | 1 + src/libstd/num/f64.rs | 1 + src/libstd/num/float.rs | 1 + src/libstd/num/int.rs | 2 + src/libstd/num/int_macros.rs | 2 + src/libstd/num/strconv.rs | 14 ++-- src/libstd/num/uint_macros.rs | 2 + src/libstd/rand.rs | 10 +-- src/libstd/str.rs | 80 +++++++++---------- src/libstd/unicode.rs | 1 + src/libstd/unstable/extfmt.rs | 1 + src/libstd/unstable/lang.rs | 8 +- src/libsyntax/diagnostic.rs | 8 +- src/libsyntax/ext/expand.rs | 2 + src/libsyntax/syntax.rs | 1 + .../lint-non-uppercase-statics.rs | 15 ++++ src/test/compile-fail/static-assert.rs | 2 +- src/test/compile-fail/static-assert2.rs | 2 +- ...ase-types-non-uppercase-statics-unicode.rs | 21 +++++ ...uppercase-statics-lowercase-mut-statics.rs | 17 ++++ 49 files changed, 272 insertions(+), 170 deletions(-) create mode 100644 src/test/compile-fail/lint-non-uppercase-statics.rs create mode 100644 src/test/run-pass/lint-non-camel-case-types-non-uppercase-statics-unicode.rs create mode 100644 src/test/run-pass/lint-non-uppercase-statics-lowercase-mut-statics.rs diff --git a/doc/rust.md b/doc/rust.md index cc53d7d17a25..1db9dac9b582 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -1107,11 +1107,11 @@ The derived types are borrowed pointers with the `'static` lifetime, fixed-size arrays, tuples, and structs. ~~~~ -static bit1: uint = 1 << 0; -static bit2: uint = 1 << 1; +static BIT1: uint = 1 << 0; +static BIT2: uint = 1 << 1; -static bits: [uint, ..2] = [bit1, bit2]; -static string: &'static str = "bitstring"; +static BITS: [uint, ..2] = [BIT1, BIT2]; +static STRING: &'static str = "bitstring"; struct BitsNStrings<'self> { mybits: [uint, ..2], @@ -1119,8 +1119,8 @@ struct BitsNStrings<'self> { } static bits_n_strings: BitsNStrings<'static> = BitsNStrings { - mybits: bits, - mystring: string + mybits: BITS, + mystring: STRING }; ~~~~ diff --git a/doc/tutorial.md b/doc/tutorial.md index aa6e90826bbb..1f552ab9458d 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -237,8 +237,8 @@ can specify a variable's type by following it with a colon, then the type name. Static items, on the other hand, always require a type annotation. ~~~~ -static monster_factor: float = 57.8; -let monster_size = monster_factor * 10.0; +static MONSTER_FACTOR: float = 57.8; +let monster_size = MONSTER_FACTOR * 10.0; let monster_size: int = 50; ~~~~ diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 715f6d91e09d..06422a49b65f 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -79,8 +79,8 @@ fn run_rfail_test(config: &config, props: &TestProps, testfile: &Path) { }; // The value our Makefile configures valgrind to return on failure - static valgrind_err: int = 100; - if ProcRes.status == valgrind_err { + static VALGRIND_ERR: int = 100; + if ProcRes.status == VALGRIND_ERR { fatal_ProcRes(~"run-fail test isn't valgrind-clean!", &ProcRes); } @@ -102,8 +102,8 @@ fn run_rfail_test(config: &config, props: &TestProps, testfile: &Path) { fn check_correct_failure_status(ProcRes: &ProcRes) { // The value the rust runtime returns on failure - static rust_err: int = 101; - if ProcRes.status != rust_err { + static RUST_ERR: int = 101; + if ProcRes.status != RUST_ERR { fatal_ProcRes( fmt!("failure produced the wrong error code: %d", ProcRes.status), diff --git a/src/etc/unicode.py b/src/etc/unicode.py index 2a252f3f1f39..afcbc0a9859d 100755 --- a/src/etc/unicode.py +++ b/src/etc/unicode.py @@ -250,6 +250,7 @@ rf.write('''// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGH // The following code was generated by "src/etc/unicode.py" #[allow(missing_doc)]; +#[allow(non_uppercase_statics)]; ''') diff --git a/src/libextra/bitv.rs b/src/libextra/bitv.rs index 30541f832389..72b6e6dc6500 100644 --- a/src/libextra/bitv.rs +++ b/src/libextra/bitv.rs @@ -872,7 +872,7 @@ mod tests { use std::rand; use std::rand::Rng; - static bench_bits : uint = 1 << 14; + static BENCH_BITS : uint = 1 << 14; #[test] fn test_to_str() { @@ -1452,19 +1452,19 @@ mod tests { fn bench_big_bitv_big(b: &mut BenchHarness) { let mut r = rng(); let mut storage = ~[]; - storage.grow(bench_bits / uint::bits, &0); + storage.grow(BENCH_BITS / uint::bits, &0); let mut bitv = BigBitv::new(storage); do b.iter { - bitv.set((r.next() as uint) % bench_bits, true); + bitv.set((r.next() as uint) % BENCH_BITS, true); } } #[bench] fn bench_bitv_big(b: &mut BenchHarness) { let mut r = rng(); - let mut bitv = Bitv::new(bench_bits, false); + let mut bitv = Bitv::new(BENCH_BITS, false); do b.iter { - bitv.set((r.next() as uint) % bench_bits, true); + bitv.set((r.next() as uint) % BENCH_BITS, true); } } @@ -1491,14 +1491,14 @@ mod tests { let mut r = rng(); let mut bitv = BitvSet::new(); do b.iter { - bitv.insert((r.next() as uint) % bench_bits); + bitv.insert((r.next() as uint) % BENCH_BITS); } } #[bench] fn bench_bitv_big_union(b: &mut BenchHarness) { - let mut b1 = Bitv::new(bench_bits, false); - let b2 = Bitv::new(bench_bits, false); + let mut b1 = Bitv::new(BENCH_BITS, false); + let b2 = Bitv::new(BENCH_BITS, false); do b.iter { b1.union(&b2); } diff --git a/src/libextra/deque.rs b/src/libextra/deque.rs index f834860a4f70..e89c12e5848d 100644 --- a/src/libextra/deque.rs +++ b/src/libextra/deque.rs @@ -15,7 +15,7 @@ use std::util::replace; use std::vec; use std::cast::transmute; -static initial_capacity: uint = 32u; // 2^5 +static INITIAL_CAPACITY: uint = 32u; // 2^5 #[allow(missing_doc)] pub struct Deque { @@ -47,7 +47,7 @@ impl Deque { /// Create an empty Deque pub fn new() -> Deque { Deque{nelts: 0, lo: 0, hi: 0, - elts: vec::from_fn(initial_capacity, |_| None)} + elts: vec::from_fn(INITIAL_CAPACITY, |_| None)} } /// Return a reference to the first element in the deque diff --git a/src/libextra/ebml.rs b/src/libextra/ebml.rs index c79b012cfc5b..502e45e1d474 100644 --- a/src/libextra/ebml.rs +++ b/src/libextra/ebml.rs @@ -748,7 +748,7 @@ pub mod writer { // Set to true to generate more debugging in EBML code. // Totally lame approach. - static debug: bool = true; + static DEBUG: bool = true; impl Encoder { // used internally to emit things like the vector length and so on @@ -764,7 +764,7 @@ pub mod writer { // efficiency. When debugging, though, we can emit such // labels and then they will be checked by decoder to // try and check failures more quickly. - if debug { self.wr_tagged_str(EsLabel as uint, label) } + if DEBUG { self.wr_tagged_str(EsLabel as uint, label) } } } diff --git a/src/libextra/flate.rs b/src/libextra/flate.rs index 92f9f834f52d..f249feeb4403 100644 --- a/src/libextra/flate.rs +++ b/src/libextra/flate.rs @@ -39,10 +39,10 @@ pub mod rustrt { } } -static lz_none : c_int = 0x0; // Huffman-coding only. -static lz_fast : c_int = 0x1; // LZ with only one probe -static lz_norm : c_int = 0x80; // LZ with 128 probes, "normal" -static lz_best : c_int = 0xfff; // LZ with 4095 probes, "best" +static LZ_NONE : c_int = 0x0; // Huffman-coding only. +static LZ_FAST : c_int = 0x1; // LZ with only one probe +static LZ_NORM : c_int = 0x80; // LZ with 128 probes, "normal" +static LZ_BEST : c_int = 0xfff; // LZ with 4095 probes, "best" pub fn deflate_bytes(bytes: &[u8]) -> ~[u8] { do vec::as_imm_buf(bytes) |b, len| { @@ -52,7 +52,7 @@ pub fn deflate_bytes(bytes: &[u8]) -> ~[u8] { rustrt::tdefl_compress_mem_to_heap(b as *c_void, len as size_t, &mut outsz, - lz_norm); + LZ_NORM); assert!(res as int != 0); let out = vec::raw::from_buf_raw(res as *u8, outsz as uint); diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs index 9422ad0c9f2e..25aeccdcbed0 100644 --- a/src/libextra/num/bigint.rs +++ b/src/libextra/num/bigint.rs @@ -17,6 +17,7 @@ A BigInt is a combination of BigUint and Sign. */ #[allow(missing_doc)]; +#[allow(non_uppercase_statics)]; use std::cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater}; use std::int; diff --git a/src/libextra/num/complex.rs b/src/libextra/num/complex.rs index 915523443fbc..00224f8b06d9 100644 --- a/src/libextra/num/complex.rs +++ b/src/libextra/num/complex.rs @@ -191,6 +191,8 @@ impl ToStrRadix for Cmplx { #[cfg(test)] mod test { + #[allow(non_uppercase_statics)]; + use super::*; use std::num::{Zero,One,Real}; diff --git a/src/libextra/par.rs b/src/libextra/par.rs index 2878a3ee1221..2d8273656815 100644 --- a/src/libextra/par.rs +++ b/src/libextra/par.rs @@ -20,10 +20,10 @@ use future_spawn = future::spawn; * The maximum number of tasks this module will spawn for a single * operation. */ -static max_tasks : uint = 32u; +static MAX_TASKS : uint = 32u; /// The minimum number of elements each task will process. -static min_granularity : uint = 1024u; +static MIN_GRANULARITY : uint = 1024u; /** * An internal helper to map a function over a large vector and @@ -38,13 +38,13 @@ fn map_slices( -> ~[B] { let len = xs.len(); - if len < min_granularity { + if len < MIN_GRANULARITY { info!("small slice"); // This is a small vector, fall back on the normal map. ~[f()(0u, xs)] } else { - let num_tasks = uint::min(max_tasks, len / min_granularity); + let num_tasks = uint::min(MAX_TASKS, len / MIN_GRANULARITY); let items_per_task = len / num_tasks; diff --git a/src/libextra/rope.rs b/src/libextra/rope.rs index 8374c1a86e31..dd3f08917fd4 100644 --- a/src/libextra/rope.rs +++ b/src/libextra/rope.rs @@ -632,14 +632,14 @@ pub mod node { * * This is not a strict value */ - pub static hint_max_leaf_char_len: uint = 256u; + pub static HINT_MAX_LEAF_CHAR_LEN: uint = 256u; /** * The maximal height that _should_ be permitted in a tree. * * This is not a strict value */ - pub static hint_max_node_height: uint = 16u; + pub static HINT_MAX_NODE_HEIGHT: uint = 16u; /** * Adopt a string as a node. @@ -707,26 +707,26 @@ pub mod node { char_len: char_len, content: str, }); - if char_len <= hint_max_leaf_char_len { + if char_len <= HINT_MAX_LEAF_CHAR_LEN { return candidate; } else { - //Firstly, split `str` in slices of hint_max_leaf_char_len - let mut leaves = uint::div_ceil(char_len, hint_max_leaf_char_len); + //Firstly, split `str` in slices of HINT_MAX_LEAF_CHAR_LEN + let mut leaves = uint::div_ceil(char_len, HINT_MAX_LEAF_CHAR_LEN); //Number of leaves let mut nodes = vec::from_elem(leaves, candidate); let mut i = 0u; let mut offset = byte_start; let first_leaf_char_len = - if char_len%hint_max_leaf_char_len == 0u { - hint_max_leaf_char_len + if char_len%HINT_MAX_LEAF_CHAR_LEN == 0u { + HINT_MAX_LEAF_CHAR_LEN } else { - char_len%hint_max_leaf_char_len + char_len%HINT_MAX_LEAF_CHAR_LEN }; while i < leaves { let chunk_char_len: uint = if i == 0u { first_leaf_char_len } - else { hint_max_leaf_char_len }; + else { HINT_MAX_LEAF_CHAR_LEN }; let chunk_byte_len = str.slice_from(offset).slice_chars(0, chunk_char_len).len(); nodes[i] = @Leaf(Leaf { @@ -792,22 +792,22 @@ pub mod node { let right_len= char_len(right); let mut left_height= height(left); let mut right_height=height(right); - if left_len + right_len > hint_max_leaf_char_len { - if left_len <= hint_max_leaf_char_len { + if left_len + right_len > HINT_MAX_LEAF_CHAR_LEN { + if left_len <= HINT_MAX_LEAF_CHAR_LEN { left = flatten(left); left_height = height(left); } - if right_len <= hint_max_leaf_char_len { + if right_len <= HINT_MAX_LEAF_CHAR_LEN { right = flatten(right); right_height = height(right); } } - if left_height >= hint_max_node_height { + if left_height >= HINT_MAX_NODE_HEIGHT { left = of_substr_unsafer(@serialize_node(left), 0u,byte_len(left), left_len); } - if right_height >= hint_max_node_height { + if right_height >= HINT_MAX_NODE_HEIGHT { right = of_substr_unsafer(@serialize_node(right), 0u,byte_len(right), right_len); @@ -875,7 +875,7 @@ pub mod node { * * # Algorithm * - * * if the node height is smaller than `hint_max_node_height`, do nothing + * * if the node height is smaller than `HINT_MAX_NODE_HEIGHT`, do nothing * * otherwise, gather all leaves as a forest, rebuild a balanced node, * concatenating small leaves along the way * @@ -886,7 +886,7 @@ pub mod node { * as `node` bot lower height and/or fragmentation. */ pub fn bal(node: @Node) -> Option<@Node> { - if height(node) < hint_max_node_height { return None; } + if height(node) < HINT_MAX_NODE_HEIGHT { return None; } //1. Gather all leaves as a forest let mut forest = ~[]; let mut it = leaf_iterator::start(node); diff --git a/src/libextra/term.rs b/src/libextra/term.rs index e21e5c5fb585..556266227757 100644 --- a/src/libextra/term.rs +++ b/src/libextra/term.rs @@ -26,23 +26,23 @@ use std::io; pub mod color { pub type Color = u16; - pub static black: Color = 0u16; - pub static red: Color = 1u16; - pub static green: Color = 2u16; - pub static yellow: Color = 3u16; - pub static blue: Color = 4u16; - pub static magenta: Color = 5u16; - pub static cyan: Color = 6u16; - pub static white: Color = 7u16; + pub static BLACK: Color = 0u16; + pub static RED: Color = 1u16; + pub static GREEN: Color = 2u16; + pub static YELLOW: Color = 3u16; + pub static BLUE: Color = 4u16; + pub static MAGENTA: Color = 5u16; + pub static CYAN: Color = 6u16; + pub static WHITE: Color = 7u16; - pub static bright_black: Color = 8u16; - pub static bright_red: Color = 9u16; - pub static bright_green: Color = 10u16; - pub static bright_yellow: Color = 11u16; - pub static bright_blue: Color = 12u16; - pub static bright_magenta: Color = 13u16; - pub static bright_cyan: Color = 14u16; - pub static bright_white: Color = 15u16; + pub static BRIGHT_BLACK: Color = 8u16; + pub static BRIGHT_RED: Color = 9u16; + pub static BRIGHT_GREEN: Color = 10u16; + pub static BRIGHT_YELLOW: Color = 11u16; + pub static BRIGHT_BLUE: Color = 12u16; + pub static BRIGHT_MAGENTA: Color = 13u16; + pub static BRIGHT_CYAN: Color = 14u16; + pub static BRIGHT_WHITE: Color = 15u16; } #[cfg(not(target_os = "win32"))] diff --git a/src/libextra/terminfo/parser/compiled.rs b/src/libextra/terminfo/parser/compiled.rs index 063d26d1424b..e16297e38717 100644 --- a/src/libextra/terminfo/parser/compiled.rs +++ b/src/libextra/terminfo/parser/compiled.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[allow(non_uppercase_statics)]; + /// ncurses-compatible compiled terminfo format parsing (term(5)) diff --git a/src/libextra/test.rs b/src/libextra/test.rs index 1e1e53de9e89..59aed0055d87 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -331,19 +331,19 @@ pub fn run_tests_console(opts: &TestOpts, } fn write_ok(out: @io::Writer, use_color: bool) { - write_pretty(out, "ok", term::color::green, use_color); + write_pretty(out, "ok", term::color::GREEN, use_color); } fn write_failed(out: @io::Writer, use_color: bool) { - write_pretty(out, "FAILED", term::color::red, use_color); + write_pretty(out, "FAILED", term::color::RED, use_color); } fn write_ignored(out: @io::Writer, use_color: bool) { - write_pretty(out, "ignored", term::color::yellow, use_color); + write_pretty(out, "ignored", term::color::YELLOW, use_color); } fn write_bench(out: @io::Writer, use_color: bool) { - write_pretty(out, "bench", term::color::cyan, use_color); + write_pretty(out, "bench", term::color::CYAN, use_color); } fn write_pretty(out: @io::Writer, @@ -487,16 +487,16 @@ fn run_tests(opts: &TestOpts, // Windows tends to dislike being overloaded with threads. #[cfg(windows)] -static sched_overcommit : uint = 1; +static SCHED_OVERCOMMIT : uint = 1; #[cfg(unix)] -static sched_overcommit : uint = 4u; +static SCHED_OVERCOMMIT : uint = 4u; fn get_concurrency() -> uint { unsafe { let threads = rustrt::rust_sched_threads() as uint; if threads == 1 { 1 } - else { threads * sched_overcommit } + else { threads * SCHED_OVERCOMMIT } } } diff --git a/src/libextra/time.rs b/src/libextra/time.rs index e1f42934b390..a64b23743287 100644 --- a/src/libextra/time.rs +++ b/src/libextra/time.rs @@ -868,20 +868,20 @@ mod tests { use std::str; fn test_get_time() { - static some_recent_date: i64 = 1325376000i64; // 2012-01-01T00:00:00Z - static some_future_date: i64 = 1577836800i64; // 2020-01-01T00:00:00Z + static SOME_RECENT_DATE: i64 = 1325376000i64; // 2012-01-01T00:00:00Z + static SOME_FUTURE_DATE: i64 = 1577836800i64; // 2020-01-01T00:00:00Z let tv1 = get_time(); debug!("tv1=%? sec + %? nsec", tv1.sec as uint, tv1.nsec as uint); - assert!(tv1.sec > some_recent_date); + assert!(tv1.sec > SOME_RECENT_DATE); assert!(tv1.nsec < 1000000000i32); let tv2 = get_time(); debug!("tv2=%? sec + %? nsec", tv2.sec as uint, tv2.nsec as uint); assert!(tv2.sec >= tv1.sec); - assert!(tv2.sec < some_future_date); + assert!(tv2.sec < SOME_FUTURE_DATE); assert!(tv2.nsec < 1000000000i32); if tv2.sec == tv1.sec { assert!(tv2.nsec >= tv1.nsec); diff --git a/src/librust/rust.rs b/src/librust/rust.rs index 30b980a2f858..63a0ef0842e0 100644 --- a/src/librust/rust.rs +++ b/src/librust/rust.rs @@ -60,7 +60,7 @@ struct Command<'self> { usage_full: UsageSource<'self>, } -static commands: &'static [Command<'static>] = &[ +static COMMANDS: &'static [Command<'static>] = &[ Command{ cmd: "build", action: CallMain("rustc", rustc::main), @@ -122,7 +122,7 @@ fn rustc_help() { } fn find_cmd(command_string: &str) -> Option { - do commands.iter().find_ |command| { + do COMMANDS.iter().find_ |command| { command.cmd == command_string }.map_consume(|x| copy *x) } @@ -197,7 +197,7 @@ fn do_command(command: &Command, args: &[~str]) -> ValidUsage { } fn usage() { - static indent: uint = 8; + static INDENT: uint = 8; io::print( "The rust tool is a convenience for managing rust source code.\n\ @@ -209,8 +209,8 @@ fn usage() { \n" ); - for commands.iter().advance |command| { - let padding = " ".repeat(indent - command.cmd.len()); + for COMMANDS.iter().advance |command| { + let padding = " ".repeat(INDENT - command.cmd.len()); io::println(fmt!(" %s%s%s", command.cmd, padding, command.usage_line)); } diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index d7e49a822534..e345a9d703c9 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -14,7 +14,6 @@ use middle::ty; use middle::pat_util; use util::ppaux::{ty_to_str}; -use std::char; use std::cmp; use std::hashmap::HashMap; use std::i16; @@ -80,6 +79,7 @@ pub enum lint { non_implicitly_copyable_typarams, deprecated_pattern, non_camel_case_types, + non_uppercase_statics, type_limits, default_methods, unused_unsafe, @@ -198,6 +198,13 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[ default: allow }), + ("non_uppercase_statics", + LintSpec { + lint: non_uppercase_statics, + desc: "static constants should have uppercase identifiers", + default: warn + }), + ("managed_heap_memory", LintSpec { lint: managed_heap_memory, @@ -884,6 +891,23 @@ fn check_item_non_camel_case_types(cx: &Context, it: &ast::item) { } } +fn check_item_non_uppercase_statics(cx: &Context, it: &ast::item) { + match it.node { + // only check static constants + ast::item_static(_, ast::m_imm, _) => { + let s = cx.tcx.sess.str_of(it.ident); + // check for lowercase letters rather than non-uppercase + // ones (some scripts don't have a concept of + // upper/lowercase) + if s.iter().any_(|c| c.is_lowercase()) { + cx.span_lint(non_uppercase_statics, it.span, + "static constant should have an uppercase identifier"); + } + } + _ => {} + } +} + fn lint_unused_unsafe() -> visit::vt<@mut Context> { visit::mk_vt(@visit::Visitor { visit_expr: |e, (cx, vt): (@mut Context, visit::vt<@mut Context>)| { @@ -1146,6 +1170,7 @@ pub fn check_crate(tcx: ty::ctxt, crate: @ast::crate) { } check_item_ctypes(cx, it); check_item_non_camel_case_types(cx, it); + check_item_non_uppercase_statics(cx, it); check_item_default_methods(cx, it); check_item_heap(cx, it); diff --git a/src/librustc/rustc.rs b/src/librustc/rustc.rs index a930570dd173..243ddb2a14b0 100644 --- a/src/librustc/rustc.rs +++ b/src/librustc/rustc.rs @@ -19,6 +19,7 @@ #[allow(non_implicitly_copyable_typarams)]; #[allow(non_camel_case_types)]; +#[allow(non_uppercase_statics)]; #[deny(deprecated_pattern)]; extern mod extra; diff --git a/src/librustdoc/demo.rs b/src/librustdoc/demo.rs index b6728e00fe41..3393133bc186 100644 --- a/src/librustdoc/demo.rs +++ b/src/librustdoc/demo.rs @@ -23,7 +23,7 @@ /// The base price of a muffin on a non-holiday -static price_of_a_muffin: float = 70f; +static PRICE_OF_A_MUFFIN: float = 70f; struct WaitPerson { hair_color: ~str diff --git a/src/librustdoc/desc_to_brief_pass.rs b/src/librustdoc/desc_to_brief_pass.rs index 74d5d4674137..2077516a9b56 100644 --- a/src/librustdoc/desc_to_brief_pass.rs +++ b/src/librustdoc/desc_to_brief_pass.rs @@ -87,11 +87,11 @@ pub fn extract(desc: Option<~str>) -> Option<~str> { } fn parse_desc(desc: ~str) -> Option<~str> { - static max_brief_len: uint = 120u; + static MAX_BRIEF_LEN: uint = 120u; match first_sentence(copy desc) { Some(first_sentence) => { - if first_sentence.len() <= max_brief_len { + if first_sentence.len() <= MAX_BRIEF_LEN { Some(first_sentence) } else { None diff --git a/src/librustpkg/messages.rs b/src/librustpkg/messages.rs index 43d727c2989a..eec33a375355 100644 --- a/src/librustpkg/messages.rs +++ b/src/librustpkg/messages.rs @@ -13,15 +13,15 @@ use std::io; use std::result::*; pub fn note(msg: &str) { - pretty_message(msg, "note: ", term::color::green, io::stdout()) + pretty_message(msg, "note: ", term::color::GREEN, io::stdout()) } pub fn warn(msg: &str) { - pretty_message(msg, "warning: ", term::color::yellow, io::stdout()) + pretty_message(msg, "warning: ", term::color::YELLOW, io::stdout()) } pub fn error(msg: &str) { - pretty_message(msg, "error: ", term::color::red, io::stdout()) + pretty_message(msg, "error: ", term::color::RED, io::stdout()) } fn pretty_message<'a>(msg: &'a str, prefix: &'a str, color: term::color::Color, out: @io::Writer) { diff --git a/src/librustpkg/path_util.rs b/src/librustpkg/path_util.rs index 6371d7263461..b8f77ceececd 100644 --- a/src/librustpkg/path_util.rs +++ b/src/librustpkg/path_util.rs @@ -29,9 +29,9 @@ fn push_if_exists(vec: &mut ~[Path], p: &Path) { } #[cfg(windows)] -static path_entry_separator: &'static str = ";"; +static PATH_ENTRY_SEPARATOR: &'static str = ";"; #[cfg(not(windows))] -static path_entry_separator: &'static str = ":"; +static PATH_ENTRY_SEPARATOR: &'static str = ":"; /// Returns the value of RUST_PATH, as a list /// of Paths. Includes default entries for, if they exist: @@ -42,7 +42,7 @@ pub fn rust_path() -> ~[Path] { let mut env_rust_path: ~[Path] = match os::getenv("RUST_PATH") { Some(env_path) => { let env_path_components: ~[&str] = - env_path.split_str_iter(path_entry_separator).collect(); + env_path.split_str_iter(PATH_ENTRY_SEPARATOR).collect(); env_path_components.map(|&s| Path(s)) } None => ~[] @@ -56,12 +56,12 @@ pub fn rust_path() -> ~[Path] { env_rust_path } -pub static u_rwx: i32 = (S_IRUSR | S_IWUSR | S_IXUSR) as i32; +pub static U_RWX: i32 = (S_IRUSR | S_IWUSR | S_IXUSR) as i32; /// Creates a directory that is readable, writeable, /// and executable by the user. Returns true iff creation /// succeeded. -pub fn make_dir_rwx(p: &Path) -> bool { os::make_dir(p, u_rwx) } +pub fn make_dir_rwx(p: &Path) -> bool { os::make_dir(p, U_RWX) } // n.b. The next three functions ignore the package version right // now. Should fix that. @@ -318,7 +318,7 @@ fn target_file_in_workspace(pkgid: &PkgId, workspace: &Path, Lib => "lib", Main | Test | Bench => "bin" }; let result = workspace.push(subdir); - if !os::path_exists(&result) && !mkdir_recursive(&result, u_rwx) { + if !os::path_exists(&result) && !mkdir_recursive(&result, U_RWX) { cond.raise((copy result, fmt!("target_file_in_workspace couldn't \ create the %s dir (pkgid=%s, workspace=%s, what=%?, where=%?", subdir, pkgid.to_str(), workspace.to_str(), what, where))); @@ -335,7 +335,7 @@ pub fn build_pkg_id_in_workspace(pkgid: &PkgId, workspace: &Path) -> Path { // n.b. Should actually use a target-specific // subdirectory of build/ result = result.push_rel(&*pkgid.local_path); - if os::path_exists(&result) || os::mkdir_recursive(&result, u_rwx) { + if os::path_exists(&result) || os::mkdir_recursive(&result, U_RWX) { result } else { diff --git a/src/librustpkg/rustpkg.rs b/src/librustpkg/rustpkg.rs index 8ca8ae1b1edf..7c46ba2a8e75 100644 --- a/src/librustpkg/rustpkg.rs +++ b/src/librustpkg/rustpkg.rs @@ -38,7 +38,7 @@ use syntax::{ast, diagnostic}; use util::*; use messages::*; use path_util::{build_pkg_id_in_workspace, first_pkgid_src_in_workspace}; -use path_util::{u_rwx, rust_path}; +use path_util::{U_RWX, rust_path}; use path_util::{built_executable_in_workspace, built_library_in_workspace}; use path_util::{target_executable_in_workspace, target_library_in_workspace}; use workspace::{each_pkg_parent_workspace, pkg_parent_workspaces}; @@ -374,7 +374,7 @@ impl CtxMethods for Ctx { for maybe_executable.iter().advance |exec| { debug!("Copying: %s -> %s", exec.to_str(), target_exec.to_str()); - if !(os::mkdir_recursive(&target_exec.dir_path(), u_rwx) && + if !(os::mkdir_recursive(&target_exec.dir_path(), U_RWX) && os::copy_file(exec, &target_exec)) { cond.raise((copy *exec, copy target_exec)); } @@ -383,7 +383,7 @@ impl CtxMethods for Ctx { let target_lib = (copy target_lib).expect(fmt!("I built %s but apparently \ didn't install it!", lib.to_str())); debug!("Copying: %s -> %s", lib.to_str(), target_lib.to_str()); - if !(os::mkdir_recursive(&target_lib.dir_path(), u_rwx) && + if !(os::mkdir_recursive(&target_lib.dir_path(), U_RWX) && os::copy_file(lib, &target_lib)) { cond.raise((copy *lib, copy target_lib)); } diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs index b29aefdd5340..2800ad52b1eb 100644 --- a/src/librustpkg/tests.rs +++ b/src/librustpkg/tests.rs @@ -21,7 +21,7 @@ use package_source::*; use version::{ExactRevision, NoVersion, Version}; use path_util::{target_executable_in_workspace, target_library_in_workspace, target_test_in_workspace, target_bench_in_workspace, - make_dir_rwx, u_rwx, library_in_workspace, + make_dir_rwx, U_RWX, library_in_workspace, built_bench_in_workspace, built_test_in_workspace, built_library_in_workspace, built_executable_in_workspace, installed_library_in_workspace, rust_path}; @@ -78,7 +78,7 @@ fn mk_workspace(workspace: &Path, short_name: &LocalPath, version: &Version) -> // include version number in directory name let package_dir = workspace.push("src").push(fmt!("%s-%s", short_name.to_str(), version.to_str())); - assert!(os::mkdir_recursive(&package_dir, u_rwx)); + assert!(os::mkdir_recursive(&package_dir, U_RWX)); package_dir } @@ -92,7 +92,7 @@ fn mk_temp_workspace(short_name: &LocalPath, version: &Version) -> Path { os::path_is_dir(&package_dir)); // Create main, lib, test, and bench files debug!("mk_workspace: creating %s", package_dir.to_str()); - assert!(os::mkdir_recursive(&package_dir, u_rwx)); + assert!(os::mkdir_recursive(&package_dir, U_RWX)); debug!("Created %s and does it exist? %?", package_dir.to_str(), os::path_is_dir(&package_dir)); // Create main, lib, test, and bench files @@ -181,7 +181,7 @@ fn create_local_package_in(pkgid: &PkgId, pkgdir: &Path) -> Path { let package_dir = pkgdir.push("src").push(pkgid.to_str()); // Create main, lib, test, and bench files - assert!(os::mkdir_recursive(&package_dir, u_rwx)); + assert!(os::mkdir_recursive(&package_dir, U_RWX)); debug!("Created %s and does it exist? %?", package_dir.to_str(), os::path_is_dir(&package_dir)); // Create main, lib, test, and bench files @@ -589,9 +589,9 @@ fn rust_path_test() { fn rust_path_contents() { let dir = mkdtemp(&os::tmpdir(), "rust_path").expect("rust_path_contents failed"); let abc = &dir.push("A").push("B").push("C"); - assert!(os::mkdir_recursive(&abc.push(".rust"), u_rwx)); - assert!(os::mkdir_recursive(&abc.pop().push(".rust"), u_rwx)); - assert!(os::mkdir_recursive(&abc.pop().pop().push(".rust"), u_rwx)); + assert!(os::mkdir_recursive(&abc.push(".rust"), U_RWX)); + assert!(os::mkdir_recursive(&abc.pop().push(".rust"), U_RWX)); + assert!(os::mkdir_recursive(&abc.pop().pop().push(".rust"), U_RWX)); assert!(do os::change_dir_locked(&dir.push("A").push("B").push("C")) { let p = rust_path(); let cwd = os::getcwd().push(".rust"); diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index 26e26add3dc2..669e5042d3bf 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -28,7 +28,7 @@ use search::find_library_in_search_path; use path_util::target_library_in_workspace; pub use target::{OutputType, Main, Lib, Bench, Test}; -static Commands: &'static [&'static str] = +static COMMANDS: &'static [&'static str] = &["build", "clean", "do", "info", "install", "prefer", "test", "uninstall", "unprefer"]; @@ -55,7 +55,7 @@ pub fn root() -> Path { } pub fn is_cmd(cmd: &str) -> bool { - Commands.iter().any_(|&c| c == cmd) + COMMANDS.iter().any_(|&c| c == cmd) } struct ListenerFn { @@ -417,4 +417,4 @@ mod test { // tjc: cheesy fn debug_flags() -> ~[~str] { ~[] } -// static debug_flags: ~[~str] = ~[~"-Z", ~"time-passes"]; +// static DEBUG_FLAGS: ~[~str] = ~[~"-Z", ~"time-passes"]; diff --git a/src/libstd/gc.rs b/src/libstd/gc.rs index c9e33219fa50..f92561edcb08 100644 --- a/src/libstd/gc.rs +++ b/src/libstd/gc.rs @@ -9,6 +9,7 @@ // except according to those terms. #[doc(hidden)]; +#[allow(non_uppercase_statics)]; /*! Precise garbage collector diff --git a/src/libstd/libc.rs b/src/libstd/libc.rs index 41b78afded1a..e51119859fb3 100644 --- a/src/libstd/libc.rs +++ b/src/libstd/libc.rs @@ -64,6 +64,7 @@ */ #[allow(non_camel_case_types)]; +#[allow(non_uppercase_statics)]; #[allow(missing_doc)]; // Initial glob-exports mean that all the contents of all the modules diff --git a/src/libstd/num/cmath.rs b/src/libstd/num/cmath.rs index 96d3b79e3385..c89fc73693ca 100644 --- a/src/libstd/num/cmath.rs +++ b/src/libstd/num/cmath.rs @@ -9,6 +9,7 @@ // except according to those terms. #[allow(missing_doc)]; +#[allow(non_uppercase_statics)]; // function names are almost identical to C's libmath, a few have been // renamed, grep for "rename:" diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index 0b6eb766b299..a84c27cd9188 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -10,6 +10,7 @@ //! Operations and constants for `f32` #[allow(missing_doc)]; +#[allow(non_uppercase_statics)]; use libc::c_int; use num::{Zero, One, strconv}; diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index c39c7a3a57d2..216963e04143 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -11,6 +11,7 @@ //! Operations and constants for `f64` #[allow(missing_doc)]; +#[allow(non_uppercase_statics)]; use libc::c_int; use num::{Zero, One, strconv}; diff --git a/src/libstd/num/float.rs b/src/libstd/num/float.rs index 7a6e3042e7b7..d73ff16c6f7b 100644 --- a/src/libstd/num/float.rs +++ b/src/libstd/num/float.rs @@ -21,6 +21,7 @@ // PORT this must match in width according to architecture #[allow(missing_doc)]; +#[allow(non_uppercase_statics)]; use f64; use libc::c_int; diff --git a/src/libstd/num/int.rs b/src/libstd/num/int.rs index d3c2733b47d5..d39b4b2b911f 100644 --- a/src/libstd/num/int.rs +++ b/src/libstd/num/int.rs @@ -10,6 +10,8 @@ //! Operations and constants for `int` +#[allow(non_uppercase_statics)]; + use num::BitCount; pub use self::generated::*; diff --git a/src/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs index f152d60cb7a3..c2eebf9a3e41 100644 --- a/src/libstd/num/int_macros.rs +++ b/src/libstd/num/int_macros.rs @@ -14,6 +14,8 @@ macro_rules! int_module (($T:ty, $bits:expr) => (mod generated { +#[allow(non_uppercase_statics)]; + use num::{ToStrRadix, FromStrRadix}; use num::{Zero, One, strconv}; use prelude::*; diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs index f6dff4267b7a..337d804ce732 100644 --- a/src/libstd/num/strconv.rs +++ b/src/libstd/num/strconv.rs @@ -101,12 +101,12 @@ impl_NumStrConv_Integer!(u64) // Special value strings as [u8] consts. -static inf_buf: [u8, ..3] = ['i' as u8, 'n' as u8, 'f' as u8]; -static positive_inf_buf: [u8, ..4] = ['+' as u8, 'i' as u8, 'n' as u8, +static INF_BUF: [u8, ..3] = ['i' as u8, 'n' as u8, 'f' as u8]; +static POS_INF_BUF: [u8, ..4] = ['+' as u8, 'i' as u8, 'n' as u8, 'f' as u8]; -static negative_inf_buf: [u8, ..4] = ['-' as u8, 'i' as u8, 'n' as u8, +static NEG_INF_BUF: [u8, ..4] = ['-' as u8, 'i' as u8, 'n' as u8, 'f' as u8]; -static nan_buf: [u8, ..3] = ['N' as u8, 'a' as u8, 'N' as u8]; +static NAN_BUF: [u8, ..3] = ['N' as u8, 'a' as u8, 'N' as u8]; /** * Converts an integral number to its string representation as a byte vector. @@ -506,15 +506,15 @@ pub fn from_str_bytes_common+ } if special { - if buf == inf_buf || buf == positive_inf_buf { + if buf == INF_BUF || buf == POS_INF_BUF { return NumStrConv::inf(); - } else if buf == negative_inf_buf { + } else if buf == NEG_INF_BUF { if negative { return NumStrConv::neg_inf(); } else { return None; } - } else if buf == nan_buf { + } else if buf == NAN_BUF { return NumStrConv::NaN(); } } diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs index 25e338fcd0f6..d185b2a05a8c 100644 --- a/src/libstd/num/uint_macros.rs +++ b/src/libstd/num/uint_macros.rs @@ -14,6 +14,8 @@ macro_rules! uint_module (($T:ty, $T_SIGNED:ty, $bits:expr) => (mod generated { +#[allow(non_uppercase_statics)]; + use num::BitCount; use num::{ToStrRadix, FromStrRadix}; use num::{Zero, One, strconv}; diff --git a/src/libstd/rand.rs b/src/libstd/rand.rs index 5f96e38a55af..5782822bc2b7 100644 --- a/src/libstd/rand.rs +++ b/src/libstd/rand.rs @@ -157,7 +157,7 @@ impl Rand for f32 { } } -static scale : f64 = (u32::max_value as f64) + 1.0f64; +static SCALE : f64 = (u32::max_value as f64) + 1.0f64; impl Rand for f64 { #[inline] fn rand(rng: &mut R) -> f64 { @@ -165,7 +165,7 @@ impl Rand for f64 { let u2 = rng.next() as f64; let u3 = rng.next() as f64; - ((u1 / scale + u2) / scale + u3) / scale + ((u1 / SCALE + u2) / SCALE + u3) / SCALE } } @@ -724,7 +724,7 @@ impl IsaacRng { let mut a = self.a; let mut b = self.b + self.c; - static midpoint: uint = RAND_SIZE as uint / 2; + static MIDPOINT: uint = RAND_SIZE as uint / 2; macro_rules! ind (($x:expr) => { self.mem[($x >> 2) & (RAND_SIZE - 1)] @@ -748,9 +748,9 @@ impl IsaacRng { }} ); - let r = [(0, midpoint), (midpoint, 0)]; + let r = [(0, MIDPOINT), (MIDPOINT, 0)]; for r.iter().advance |&(mr_offset, m2_offset)| { - for uint::range_step(0, midpoint, 4) |base| { + for uint::range_step(0, MIDPOINT, 4) |base| { rngstep!(0, 13); rngstep!(1, -6); rngstep!(2, 2); diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 4115cad65594..28162cf5117c 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -602,7 +602,7 @@ pub fn is_utf8(v: &[u8]) -> bool { if i + chsize > total { return false; } i += 1u; while chsize > 1u { - if v[i] & 192u8 != tag_cont_u8 { return false; } + if v[i] & 192u8 != TAG_CONT_U8 { return false; } i += 1u; chsize -= 1u; } @@ -743,18 +743,18 @@ pub struct CharRange { } // UTF-8 tags and ranges -static tag_cont_u8: u8 = 128u8; -static tag_cont: uint = 128u; -static max_one_b: uint = 128u; -static tag_two_b: uint = 192u; -static max_two_b: uint = 2048u; -static tag_three_b: uint = 224u; -static max_three_b: uint = 65536u; -static tag_four_b: uint = 240u; -static max_four_b: uint = 2097152u; -static tag_five_b: uint = 248u; -static max_five_b: uint = 67108864u; -static tag_six_b: uint = 252u; +static TAG_CONT_U8: u8 = 128u8; +static TAG_CONT: uint = 128u; +static MAX_ONE_B: uint = 128u; +static TAG_TWO_B: uint = 192u; +static MAX_TWO_B: uint = 2048u; +static TAG_THREE_B: uint = 224u; +static MAX_THREE_B: uint = 65536u; +static TAG_FOUR_B: uint = 240u; +static MAX_FOUR_B: uint = 2097152u; +static TAG_FIVE_B: uint = 248u; +static MAX_FIVE_B: uint = 67108864u; +static TAG_SIX_B: uint = 252u; /** * A dummy trait to hold all the utility methods that we implement on strings. @@ -1728,7 +1728,7 @@ impl<'self> StrSlice<'self> for &'self str { let mut i = i + 1u; while i < end { let byte = self[i]; - assert_eq!(byte & 192u8, tag_cont_u8); + assert_eq!(byte & 192u8, TAG_CONT_U8); val <<= 6u; val += (byte & 63u8) as uint; i += 1u; @@ -1755,7 +1755,7 @@ impl<'self> StrSlice<'self> for &'self str { let mut prev = start; // while there is a previous byte == 10...... - while prev > 0u && self[prev - 1u] & 192u8 == tag_cont_u8 { + while prev > 0u && self[prev - 1u] & 192u8 == TAG_CONT_U8 { prev -= 1u; } @@ -2071,11 +2071,11 @@ impl OwnedStr for ~str { fn push_char(&mut self, c: char) { unsafe { let code = c as uint; - let nb = if code < max_one_b { 1u } - else if code < max_two_b { 2u } - else if code < max_three_b { 3u } - else if code < max_four_b { 4u } - else if code < max_five_b { 5u } + let nb = if code < MAX_ONE_B { 1u } + else if code < MAX_TWO_B { 2u } + else if code < MAX_THREE_B { 3u } + else if code < MAX_FOUR_B { 4u } + else if code < MAX_FIVE_B { 5u } else { 6u }; let len = self.len(); let new_len = len + nb; @@ -2088,34 +2088,34 @@ impl OwnedStr for ~str { *ptr::mut_offset(buf, off) = code as u8; } 2u => { - *ptr::mut_offset(buf, off) = (code >> 6u & 31u | tag_two_b) as u8; - *ptr::mut_offset(buf, off + 1u) = (code & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off) = (code >> 6u & 31u | TAG_TWO_B) as u8; + *ptr::mut_offset(buf, off + 1u) = (code & 63u | TAG_CONT) as u8; } 3u => { - *ptr::mut_offset(buf, off) = (code >> 12u & 15u | tag_three_b) as u8; - *ptr::mut_offset(buf, off + 1u) = (code >> 6u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 2u) = (code & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off) = (code >> 12u & 15u | TAG_THREE_B) as u8; + *ptr::mut_offset(buf, off + 1u) = (code >> 6u & 63u | TAG_CONT) as u8; + *ptr::mut_offset(buf, off + 2u) = (code & 63u | TAG_CONT) as u8; } 4u => { - *ptr::mut_offset(buf, off) = (code >> 18u & 7u | tag_four_b) as u8; - *ptr::mut_offset(buf, off + 1u) = (code >> 12u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 2u) = (code >> 6u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 3u) = (code & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off) = (code >> 18u & 7u | TAG_FOUR_B) as u8; + *ptr::mut_offset(buf, off + 1u) = (code >> 12u & 63u | TAG_CONT) as u8; + *ptr::mut_offset(buf, off + 2u) = (code >> 6u & 63u | TAG_CONT) as u8; + *ptr::mut_offset(buf, off + 3u) = (code & 63u | TAG_CONT) as u8; } 5u => { - *ptr::mut_offset(buf, off) = (code >> 24u & 3u | tag_five_b) as u8; - *ptr::mut_offset(buf, off + 1u) = (code >> 18u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 2u) = (code >> 12u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 3u) = (code >> 6u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 4u) = (code & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off) = (code >> 24u & 3u | TAG_FIVE_B) as u8; + *ptr::mut_offset(buf, off + 1u) = (code >> 18u & 63u | TAG_CONT) as u8; + *ptr::mut_offset(buf, off + 2u) = (code >> 12u & 63u | TAG_CONT) as u8; + *ptr::mut_offset(buf, off + 3u) = (code >> 6u & 63u | TAG_CONT) as u8; + *ptr::mut_offset(buf, off + 4u) = (code & 63u | TAG_CONT) as u8; } 6u => { - *ptr::mut_offset(buf, off) = (code >> 30u & 1u | tag_six_b) as u8; - *ptr::mut_offset(buf, off + 1u) = (code >> 24u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 2u) = (code >> 18u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 3u) = (code >> 12u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 4u) = (code >> 6u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 5u) = (code & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off) = (code >> 30u & 1u | TAG_SIX_B) as u8; + *ptr::mut_offset(buf, off + 1u) = (code >> 24u & 63u | TAG_CONT) as u8; + *ptr::mut_offset(buf, off + 2u) = (code >> 18u & 63u | TAG_CONT) as u8; + *ptr::mut_offset(buf, off + 3u) = (code >> 12u & 63u | TAG_CONT) as u8; + *ptr::mut_offset(buf, off + 4u) = (code >> 6u & 63u | TAG_CONT) as u8; + *ptr::mut_offset(buf, off + 5u) = (code & 63u | TAG_CONT) as u8; } _ => {} } diff --git a/src/libstd/unicode.rs b/src/libstd/unicode.rs index 1e2d5c76feaa..460c0a847c8b 100644 --- a/src/libstd/unicode.rs +++ b/src/libstd/unicode.rs @@ -11,6 +11,7 @@ // The following code was generated by "src/etc/unicode.py" #[allow(missing_doc)]; +#[allow(non_uppercase_statics)]; pub mod general_category { diff --git a/src/libstd/unstable/extfmt.rs b/src/libstd/unstable/extfmt.rs index 624062a7ec40..b1df5175c920 100644 --- a/src/libstd/unstable/extfmt.rs +++ b/src/libstd/unstable/extfmt.rs @@ -472,6 +472,7 @@ pub mod ct { // conditions can be evaluated at compile-time. For now though it's cleaner to // implement it this way, I think. #[doc(hidden)] +#[allow(non_uppercase_statics)] pub mod rt { use float; use str; diff --git a/src/libstd/unstable/lang.rs b/src/libstd/unstable/lang.rs index fddd847af341..94617b4e49f0 100644 --- a/src/libstd/unstable/lang.rs +++ b/src/libstd/unstable/lang.rs @@ -197,15 +197,15 @@ impl DebugPrints for io::fd_t { fn write_hex(&self, mut i: uint) { let letters = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']; - static uint_nibbles: uint = ::uint::bytes << 1; - let mut buffer = [0_u8, ..uint_nibbles+1]; - let mut c = uint_nibbles; + static UINT_NIBBLES: uint = ::uint::bytes << 1; + let mut buffer = [0_u8, ..UINT_NIBBLES+1]; + let mut c = UINT_NIBBLES; while c > 0 { c -= 1; buffer[c] = letters[i & 0xF] as u8; i >>= 4; } - self.write(buffer.slice(0, uint_nibbles)); + self.write(buffer.slice(0, UINT_NIBBLES)); } unsafe fn write_cstr(&self, p: *c_char) { diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index ab7d3fda5013..204028212d62 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -179,10 +179,10 @@ fn diagnosticstr(lvl: level) -> ~str { fn diagnosticcolor(lvl: level) -> term::color::Color { match lvl { - fatal => term::color::bright_red, - error => term::color::bright_red, - warning => term::color::bright_yellow, - note => term::color::bright_green + fatal => term::color::BRIGHT_RED, + error => term::color::BRIGHT_RED, + warning => term::color::BRIGHT_YELLOW, + note => term::color::BRIGHT_GREEN } } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 15f915ba4d8d..a78a18810a8d 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -580,6 +580,7 @@ pub fn core_macros() -> @str { pub mod $c { fn key(_x: @::std::condition::Handler<$in,$out>) { } + #[allow(non_uppercase_statics)] pub static cond : ::std::condition::Condition<'static,$in,$out> = ::std::condition::Condition { @@ -595,6 +596,7 @@ pub fn core_macros() -> @str { pub mod $c { fn key(_x: @::std::condition::Handler<$in,$out>) { } + #[allow(non_uppercase_statics)] pub static cond : ::std::condition::Condition<'static,$in,$out> = ::std::condition::Condition { diff --git a/src/libsyntax/syntax.rs b/src/libsyntax/syntax.rs index 830ca5694553..52ed49ea1ea4 100644 --- a/src/libsyntax/syntax.rs +++ b/src/libsyntax/syntax.rs @@ -21,6 +21,7 @@ #[crate_type = "lib"]; #[allow(non_camel_case_types)]; +#[allow(non_uppercase_statics)]; #[deny(deprecated_pattern)]; extern mod extra; diff --git a/src/test/compile-fail/lint-non-uppercase-statics.rs b/src/test/compile-fail/lint-non-uppercase-statics.rs new file mode 100644 index 000000000000..4da4d3ada384 --- /dev/null +++ b/src/test/compile-fail/lint-non-uppercase-statics.rs @@ -0,0 +1,15 @@ +// Copyright 2013 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[forbid(non_uppercase_statics)]; + +static foo: int = 1; //~ ERROR static constant should have an uppercase identifier + +fn main() { } diff --git a/src/test/compile-fail/static-assert.rs b/src/test/compile-fail/static-assert.rs index 06f8c9f1a325..019a4b88aedf 100644 --- a/src/test/compile-fail/static-assert.rs +++ b/src/test/compile-fail/static-assert.rs @@ -1,5 +1,5 @@ #[static_assert] -static a: bool = false; //~ ERROR static assertion failed +static A: bool = false; //~ ERROR static assertion failed fn main() { } diff --git a/src/test/compile-fail/static-assert2.rs b/src/test/compile-fail/static-assert2.rs index de1c6427e14b..42e475dac8b6 100644 --- a/src/test/compile-fail/static-assert2.rs +++ b/src/test/compile-fail/static-assert2.rs @@ -1,4 +1,4 @@ #[static_assert] -static e: bool = 1 == 2; //~ ERROR static assertion failed +static E: bool = 1 == 2; //~ ERROR static assertion failed fn main() {} diff --git a/src/test/run-pass/lint-non-camel-case-types-non-uppercase-statics-unicode.rs b/src/test/run-pass/lint-non-camel-case-types-non-uppercase-statics-unicode.rs new file mode 100644 index 000000000000..8c1dc366f232 --- /dev/null +++ b/src/test/run-pass/lint-non-camel-case-types-non-uppercase-statics-unicode.rs @@ -0,0 +1,21 @@ +// Copyright 2013 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[forbid(non_camel_case_types)]; +#[forbid(non_uppercase_statics)]; + +// Some scripts (e.g. hiragana) don't have a concept of +// upper/lowercase + +struct ヒ; + +static ラ: uint = 0; + +fn main() {} diff --git a/src/test/run-pass/lint-non-uppercase-statics-lowercase-mut-statics.rs b/src/test/run-pass/lint-non-uppercase-statics-lowercase-mut-statics.rs new file mode 100644 index 000000000000..3a3648fbf6d8 --- /dev/null +++ b/src/test/run-pass/lint-non-uppercase-statics-lowercase-mut-statics.rs @@ -0,0 +1,17 @@ +// Copyright 2013 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + + +#[forbid(non_camel_case_types)]; +#[forbid(non_uppercase_statics)]; + +static mut bar: int = 2; + +fn main() {} From 8aa26ad4547007996e1c3c0f1aa941ea8689b5a6 Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Tue, 2 Jul 2013 01:08:51 +0900 Subject: [PATCH 11/93] Fix dereference of temporary immediate newtype structs --- src/librustc/middle/trans/datum.rs | 9 ++++++++- src/test/run-pass/newtype-temporary.rs | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 src/test/run-pass/newtype-temporary.rs diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs index b9829fd47c1a..8ee4b6644cbe 100644 --- a/src/librustc/middle/trans/datum.rs +++ b/src/librustc/middle/trans/datum.rs @@ -690,7 +690,14 @@ impl Datum { } ByValue => { assert!(ty::type_is_immediate(bcx.tcx(), ty)); - (Some(Datum {ty: ty, ..*self}), bcx) + ( + Some(Datum { + val: ExtractValue(bcx, self.val, 0), + ty: ty, + mode: ByValue + }), + bcx + ) } } } diff --git a/src/test/run-pass/newtype-temporary.rs b/src/test/run-pass/newtype-temporary.rs new file mode 100644 index 000000000000..d2407f3d6059 --- /dev/null +++ b/src/test/run-pass/newtype-temporary.rs @@ -0,0 +1,19 @@ +// Copyright 2013 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct Foo(uint); + +fn foo() -> Foo { + Foo(42) +} + +fn main() { + assert_eq!(*foo(), 42); +} From af30fe25a58c5eb1ac088f824b22621ed3652976 Mon Sep 17 00:00:00 2001 From: Sankha Narayan Guria Date: Mon, 1 Jul 2013 23:17:43 +0530 Subject: [PATCH 12/93] Improve the attempted dynamic environment-capture error message --- src/librustc/middle/kind.rs | 5 +++-- src/librustc/middle/resolve.rs | 6 ++++-- src/test/compile-fail/bad-env-capture.rs | 2 +- src/test/compile-fail/bad-env-capture2.rs | 2 +- src/test/compile-fail/bad-env-capture3.rs | 2 +- src/test/compile-fail/capture1.rs | 2 +- src/test/compile-fail/issue-3021-b.rs | 2 +- src/test/compile-fail/issue-3021-d.rs | 4 ++-- src/test/compile-fail/issue-3021.rs | 2 +- 9 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index a207985e64c8..cba094d619e0 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -198,8 +198,9 @@ fn with_appropriate_checker(cx: Context, id: node_id, fn check_for_bare(cx: Context, fv: @freevar_entry) { cx.tcx.sess.span_err( fv.span, - "attempted dynamic environment capture"); - } + "can't capture dynamic environment in a fn item; \ + use the || { ... } closure form instead"); + } // same check is done in resolve.rs, but shouldn't be done let fty = ty::node_id_to_type(cx.tcx, id); match ty::get(fty).sty { diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 06147894d446..f8adb1bbb0a4 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -3382,7 +3382,8 @@ impl Resolver { self.session.span_err( span, - "attempted dynamic environment-capture"); + "can't capture dynamic environment in a fn item; \ + use the || { ... } closure form instead"); } else { // This was an attempt to use a type parameter outside // its scope. @@ -3404,7 +3405,8 @@ impl Resolver { self.session.span_err( span, - "attempted dynamic environment-capture"); + "can't capture dynamic environment in a fn item; \ + use the || { ... } closure form instead"); } else { // This was an attempt to use a type parameter outside // its scope. diff --git a/src/test/compile-fail/bad-env-capture.rs b/src/test/compile-fail/bad-env-capture.rs index c1eb39c466aa..ac5a4c220a4a 100644 --- a/src/test/compile-fail/bad-env-capture.rs +++ b/src/test/compile-fail/bad-env-capture.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: attempted dynamic environment-capture +// error-pattern: can't capture dynamic environment in a fn item; fn foo() { let x: int; fn bar() { log(debug, x); } diff --git a/src/test/compile-fail/bad-env-capture2.rs b/src/test/compile-fail/bad-env-capture2.rs index a6d4d71242b7..c97069acd9ae 100644 --- a/src/test/compile-fail/bad-env-capture2.rs +++ b/src/test/compile-fail/bad-env-capture2.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: attempted dynamic environment-capture +// error-pattern: can't capture dynamic environment in a fn item; fn foo(x: int) { fn bar() { log(debug, x); } } diff --git a/src/test/compile-fail/bad-env-capture3.rs b/src/test/compile-fail/bad-env-capture3.rs index 9e26faf32e7c..e3a6ac2cdfc4 100644 --- a/src/test/compile-fail/bad-env-capture3.rs +++ b/src/test/compile-fail/bad-env-capture3.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: attempted dynamic environment-capture +// error-pattern: can't capture dynamic environment in a fn item; fn foo(x: int) { fn mth() { fn bar() { log(debug, x); } diff --git a/src/test/compile-fail/capture1.rs b/src/test/compile-fail/capture1.rs index 290dc7088822..706edd0a112b 100644 --- a/src/test/compile-fail/capture1.rs +++ b/src/test/compile-fail/capture1.rs @@ -10,7 +10,7 @@ // except according to those terms. -// error-pattern: attempted dynamic environment-capture +// error-pattern: can't capture dynamic environment in a fn item; fn main() { let bar: int = 5; diff --git a/src/test/compile-fail/issue-3021-b.rs b/src/test/compile-fail/issue-3021-b.rs index d3aec178c238..641403fb85a1 100644 --- a/src/test/compile-fail/issue-3021-b.rs +++ b/src/test/compile-fail/issue-3021-b.rs @@ -18,7 +18,7 @@ fn siphash(k0 : u64) { impl siphash { pub fn reset(&mut self) { - self.v0 = k0 ^ 0x736f6d6570736575; //~ ERROR attempted dynamic environment-capture + self.v0 = k0 ^ 0x736f6d6570736575; //~ ERROR can't capture dynamic environment //~^ ERROR unresolved name `k0`. } } diff --git a/src/test/compile-fail/issue-3021-d.rs b/src/test/compile-fail/issue-3021-d.rs index c6b5d8c42d59..c5ee9e8bb90e 100644 --- a/src/test/compile-fail/issue-3021-d.rs +++ b/src/test/compile-fail/issue-3021-d.rs @@ -30,9 +30,9 @@ fn siphash(k0 : u64, k1 : u64) -> siphash { impl siphash for SipState { fn reset(&self) { - self.v0 = k0 ^ 0x736f6d6570736575; //~ ERROR attempted dynamic environment-capture + self.v0 = k0 ^ 0x736f6d6570736575; //~ ERROR can't capture dynamic environment //~^ ERROR unresolved name `k0`. - self.v1 = k1 ^ 0x646f72616e646f6d; //~ ERROR attempted dynamic environment-capture + self.v1 = k1 ^ 0x646f72616e646f6d; //~ ERROR can't capture dynamic environment //~^ ERROR unresolved name `k1`. } fn result(&self) -> u64 { return mk_result(self); } diff --git a/src/test/compile-fail/issue-3021.rs b/src/test/compile-fail/issue-3021.rs index 0ca6173275cb..56ade814db02 100644 --- a/src/test/compile-fail/issue-3021.rs +++ b/src/test/compile-fail/issue-3021.rs @@ -21,7 +21,7 @@ fn siphash(k0 : u64) -> SipHash { impl SipHash for SipState { fn reset(&self) { - self.v0 = k0 ^ 0x736f6d6570736575; //~ ERROR attempted dynamic environment-capture + self.v0 = k0 ^ 0x736f6d6570736575; //~ ERROR can't capture dynamic environment //~^ ERROR unresolved name `k0`. } } From 313dd37acb78b9fba701e9aebb0a01cb70b98db1 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Mon, 1 Jul 2013 15:38:57 -0400 Subject: [PATCH 13/93] Better error messages in report_use_of_moved_value; close #7286 --- src/librustc/middle/borrowck/mod.rs | 31 ++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index 7d667c2043c1..2e3813f57e08 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -538,12 +538,13 @@ impl BorrowckCtxt { move_data::MoveExpr(expr) => { let expr_ty = ty::expr_ty_adjusted(self.tcx, expr); + let suggestion = move_suggestion(self.tcx, expr_ty, + "moved by default (use `copy` to override)"); self.tcx.sess.span_note( expr.span, - fmt!("`%s` moved here because it has type `%s`, \ - which is moved by default (use `copy` to override)", + fmt!("`%s` moved here because it has type `%s`, which is %s", self.loan_path_to_str(moved_lp), - expr_ty.user_string(self.tcx))); + expr_ty.user_string(self.tcx), suggestion)); } move_data::MovePat(pat) => { @@ -557,12 +558,28 @@ impl BorrowckCtxt { } move_data::Captured(expr) => { + let expr_ty = ty::expr_ty_adjusted(self.tcx, expr); + let suggestion = move_suggestion(self.tcx, expr_ty, + "moved by default (make a copy and \ + capture that instead to override)"); self.tcx.sess.span_note( expr.span, - fmt!("`%s` moved into closure environment here \ - because its type is moved by default \ - (make a copy and capture that instead to override)", - self.loan_path_to_str(moved_lp))); + fmt!("`%s` moved into closure environment here because it \ + has type `%s`, which is %s", + self.loan_path_to_str(moved_lp), + expr_ty.user_string(self.tcx), suggestion)); + } + } + + fn move_suggestion(tcx: ty::ctxt, ty: ty::t, default_msg: &'static str) + -> &'static str { + match ty::get(ty).sty { + ty::ty_closure(ref cty) if cty.sigil == ast::BorrowedSigil => + "a non-copyable stack closure (capture it in a new closure, \ + e.g. `|x| f(x)`, to override)", + _ if !ty::type_is_copyable(tcx, ty) => + "non-copyable (perhaps you meant to use clone()?)", + _ => default_msg, } } } From 919f5a7e687052b317028d1ba26f9d3c01ed94d4 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Mon, 1 Jul 2013 15:54:54 -0400 Subject: [PATCH 14/93] Fix filenames of some compile-fail tests. --- ...osure-2.rs => closure-bounds-cant-mutably-borrow-with-copy.rs} | 0 ...osure.rs => moves-based-on-type-no-recursive-stack-closure.rs} | 0 .../{move-based-on-type-tuple.rs => moves-based-on-type-tuple.rs} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename src/test/compile-fail/{the-case-of-the-recurring-closure-2.rs => closure-bounds-cant-mutably-borrow-with-copy.rs} (100%) rename src/test/compile-fail/{the-case-of-the-recurring-closure.rs => moves-based-on-type-no-recursive-stack-closure.rs} (100%) rename src/test/compile-fail/{move-based-on-type-tuple.rs => moves-based-on-type-tuple.rs} (100%) diff --git a/src/test/compile-fail/the-case-of-the-recurring-closure-2.rs b/src/test/compile-fail/closure-bounds-cant-mutably-borrow-with-copy.rs similarity index 100% rename from src/test/compile-fail/the-case-of-the-recurring-closure-2.rs rename to src/test/compile-fail/closure-bounds-cant-mutably-borrow-with-copy.rs diff --git a/src/test/compile-fail/the-case-of-the-recurring-closure.rs b/src/test/compile-fail/moves-based-on-type-no-recursive-stack-closure.rs similarity index 100% rename from src/test/compile-fail/the-case-of-the-recurring-closure.rs rename to src/test/compile-fail/moves-based-on-type-no-recursive-stack-closure.rs diff --git a/src/test/compile-fail/move-based-on-type-tuple.rs b/src/test/compile-fail/moves-based-on-type-tuple.rs similarity index 100% rename from src/test/compile-fail/move-based-on-type-tuple.rs rename to src/test/compile-fail/moves-based-on-type-tuple.rs From 54e01eb7e0ea74c01a797f56e2bf602c298a9769 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Mon, 1 Jul 2013 18:05:46 -0400 Subject: [PATCH 15/93] Add a run-pass test for recursive copyable stack closures. --- .../closure-bounds-recursive-stack-closure.rs | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/test/run-pass/closure-bounds-recursive-stack-closure.rs diff --git a/src/test/run-pass/closure-bounds-recursive-stack-closure.rs b/src/test/run-pass/closure-bounds-recursive-stack-closure.rs new file mode 100644 index 000000000000..8bb57ebaaf58 --- /dev/null +++ b/src/test/run-pass/closure-bounds-recursive-stack-closure.rs @@ -0,0 +1,31 @@ +// Copyright 2013 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Ensures that it's legal to create a recursive stack closure as long as +// its environment is copyable + +struct R<'self> { + // This struct is needed to create the + // otherwise infinite type of a fn that + // accepts itself as argument: + c: &'self fn:Copy(&R, uint) -> uint +} + +fn main() { + // Stupid version of fibonacci. + let fib: &fn:Copy(&R, uint) -> uint = |fib, x| { + if x == 0 || x == 1 { + x + } else { + (fib.c)(fib, x-1) + (fib.c)(fib, x-2) + } + }; + assert!(fib(&R { c: fib }, 7) == 13); +} From 87b61296a5cee1eaf7aecc130afa27d63887f707 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 1 Jul 2013 08:51:34 -0700 Subject: [PATCH 16/93] Compare values in TreeMap's 'lt' function Closes #5194 --- src/libextra/treemap.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index 5e898f8e59d9..4216b5a6d1af 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -57,23 +57,25 @@ impl Eq for TreeMap { } // Lexicographical comparison -fn lt(a: &TreeMap, +fn lt(a: &TreeMap, b: &TreeMap) -> bool { let mut x = a.iter(); let mut y = b.iter(); let (a_len, b_len) = (a.len(), b.len()); for uint::min(a_len, b_len).times { - let (key_a,_) = x.next().unwrap(); - let (key_b,_) = y.next().unwrap(); + let (key_a, value_a) = x.next().unwrap(); + let (key_b, value_b) = y.next().unwrap(); if *key_a < *key_b { return true; } if *key_a > *key_b { return false; } - }; + if *value_a < *value_b { return true; } + if *value_a > *value_b { return false; } + } a_len < b_len } -impl Ord for TreeMap { +impl Ord for TreeMap { #[inline] fn lt(&self, other: &TreeMap) -> bool { lt(self, other) } #[inline] @@ -935,7 +937,7 @@ mod test_treemap { assert!(b.insert(0, 5)); assert!(a < b); assert!(a.insert(0, 7)); - assert!(!(a < b) && !(b < a)); + assert!(!(a < b) && b < a); assert!(b.insert(-2, 0)); assert!(b < a); assert!(a.insert(-5, 2)); From 3e265e784225a6f74c21dd3cc8cc0a28947dddba Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Mon, 1 Jul 2013 23:37:11 -0700 Subject: [PATCH 17/93] Small documentation changes I'm leaving the Sized kind undocumented since it isn't fully implemented yet. --- doc/rust.md | 3 --- src/libstd/bool.rs | 1 + src/libstd/kinds.rs | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/doc/rust.md b/doc/rust.md index cc53d7d17a25..c61cbe6476ce 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -2869,9 +2869,6 @@ The kinds are: : Types of this kind can be safely sent between tasks. This kind includes scalars, owning pointers, owned closures, and structural types containing only other owned types. All `Send` types are `Static`. -`Static` - : Types of this kind do not contain any borrowed pointers; - this can be a useful guarantee for code that breaks borrowing assumptions using [`unsafe` operations](#unsafe-functions). `Copy` : This kind includes all types that can be copied. All types with sendable kind are copyable, as are managed boxes, managed closures, diff --git a/src/libstd/bool.rs b/src/libstd/bool.rs index e6be164099bf..b0b586df4b58 100644 --- a/src/libstd/bool.rs +++ b/src/libstd/bool.rs @@ -122,6 +122,7 @@ pub fn xor(a: bool, b: bool) -> bool { (a && !b) || (!a && b) } * ~~~ {.rust} * rusti> std::bool::implies(true, true) * true +* ~~~ * * ~~~ {.rust} * rusti> std::bool::implies(true, false) diff --git a/src/libstd/kinds.rs b/src/libstd/kinds.rs index f350e1061680..6c16ecc0d4ef 100644 --- a/src/libstd/kinds.rs +++ b/src/libstd/kinds.rs @@ -18,7 +18,7 @@ intrinsic properties of the type. These classifications, often called They cannot be implemented by user code, but are instead implemented by the compiler automatically for the types to which they apply. -The 4 kinds are +The 3 kinds are * Copy - types that may be copied without allocation. This includes scalar types and managed pointers, and exludes owned pointers. It From c842f1335da821fa08bbf9da9783846ac1905654 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 1 Jul 2013 18:39:27 -0700 Subject: [PATCH 18/93] Completely disable rusti on 32-bit hosts --- src/librusti/rusti.rc | 667 ------------------------------------------ src/librusti/rusti.rs | 7 +- 2 files changed, 3 insertions(+), 671 deletions(-) delete mode 100644 src/librusti/rusti.rc diff --git a/src/librusti/rusti.rc b/src/librusti/rusti.rc deleted file mode 100644 index bbc4b9ff7197..000000000000 --- a/src/librusti/rusti.rc +++ /dev/null @@ -1,667 +0,0 @@ -// Copyright 2012-2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -/*! - * rusti - A REPL using the JIT backend - * - * Rusti works by serializing state between lines of input. This means that each - * line can be run in a separate task, and the only limiting factor is that all - * local bound variables are encodable. - * - * This is accomplished by feeding in generated input to rustc for execution in - * the JIT compiler. Currently input actually gets fed in three times to get - * information about the program. - * - * - Pass #1 - * In this pass, the input is simply thrown at the parser and the input comes - * back. This validates the structure of the program, and at this stage the - * global items (fns, structs, impls, traits, etc.) are filtered from the - * input into the "global namespace". These declarations shadow all previous - * declarations of an item by the same name. - * - * - Pass #2 - * After items have been stripped, the remaining input is passed to rustc - * along with all local variables declared (initialized to nothing). This pass - * runs up to typechecking. From this, we can learn about the types of each - * bound variable, what variables are bound, and also ensure that all the - * types are encodable (the input can actually be run). - * - * - Pass #3 - * Finally, a program is generated to deserialize the local variable state, - * run the code input, and then reserialize all bindings back into a local - * hash map. Once this code runs, the input has fully been run and the REPL - * waits for new input. - * - * Encoding/decoding is done with EBML, and there is simply a map of ~str -> - * ~[u8] maintaining the values of each local binding (by name). - */ - -#[link(name = "rusti", - vers = "0.7", - uuid = "7fb5bf52-7d45-4fee-8325-5ad3311149fc", - url = "https://github.com/mozilla/rust/tree/master/src/rusti")]; - -#[license = "MIT/ASL2"]; -#[crate_type = "lib"]; - -extern mod extra; -extern mod rustc; -extern mod syntax; - -use std::{libc, io, os, task, vec}; -use std::cell::Cell; -use extra::rl; - -use rustc::driver::{driver, session}; -use syntax::{ast, diagnostic}; -use syntax::ast_util::*; -use syntax::parse::token; -use syntax::print::pprust; - -use program::Program; -use utils::*; - -mod program; -pub mod utils; - -/** - * A structure shared across REPL instances for storing history - * such as statements and view items. I wish the AST was sendable. - */ -pub struct Repl { - prompt: ~str, - binary: ~str, - running: bool, - lib_search_paths: ~[~str], - - program: Program, -} - -// Action to do after reading a :command -enum CmdAction { - action_none, - action_run_line(~str), -} - -/// Run an input string in a Repl, returning the new Repl. -fn run(mut repl: Repl, input: ~str) -> Repl { - // Build some necessary rustc boilerplate for compiling things - let binary = repl.binary.to_managed(); - let options = @session::options { - crate_type: session::unknown_crate, - binary: binary, - addl_lib_search_paths: @mut repl.lib_search_paths.map(|p| Path(*p)), - jit: true, - .. copy *session::basic_options() - }; - // Because we assume that everything is encodable (and assert so), add some - // extra helpful information if the error crops up. Otherwise people are - // bound to be very confused when they find out code is running that they - // never typed in... - let sess = driver::build_session(options, |cm, msg, lvl| { - diagnostic::emit(cm, msg, lvl); - if msg.contains("failed to find an implementation of trait") && - msg.contains("extra::serialize::Encodable") { - diagnostic::emit(cm, - "Currrently rusti serializes bound locals between \ - different lines of input. This means that all \ - values of local variables need to be encodable, \ - and this type isn't encodable", - diagnostic::note); - } - }); - let intr = token::get_ident_interner(); - - // - // Stage 1: parse the input and filter it into the program (as necessary) - // - debug!("parsing: %s", input); - let crate = parse_input(sess, binary, input); - let mut to_run = ~[]; // statements to run (emitted back into code) - let new_locals = @mut ~[]; // new locals being defined - let mut result = None; // resultant expression (to print via pp) - do find_main(crate, sess) |blk| { - // Fish out all the view items, be sure to record 'extern mod' items - // differently beause they must appear before all 'use' statements - for blk.node.view_items.iter().advance |vi| { - let s = do with_pp(intr) |pp, _| { - pprust::print_view_item(pp, *vi); - }; - match vi.node { - ast::view_item_extern_mod(*) => { - repl.program.record_extern(s); - } - ast::view_item_use(*) => { repl.program.record_view_item(s); } - } - } - - // Iterate through all of the block's statements, inserting them into - // the correct portions of the program - for blk.node.stmts.iter().advance |stmt| { - let s = do with_pp(intr) |pp, _| { pprust::print_stmt(pp, *stmt); }; - match stmt.node { - ast::stmt_decl(d, _) => { - match d.node { - ast::decl_item(it) => { - let name = sess.str_of(it.ident); - match it.node { - // Structs are treated specially because to make - // them at all usable they need to be decorated - // with #[deriving(Encoable, Decodable)] - ast::item_struct(*) => { - repl.program.record_struct(name, s); - } - // Item declarations are hoisted out of main() - _ => { repl.program.record_item(name, s); } - } - } - - // Local declarations must be specially dealt with, - // record all local declarations for use later on - ast::decl_local(l) => { - let mutbl = l.node.is_mutbl; - do each_binding(l) |path, _| { - let s = do with_pp(intr) |pp, _| { - pprust::print_path(pp, path, false); - }; - new_locals.push((s, mutbl)); - } - to_run.push(s); - } - } - } - - // run statements with expressions (they have effects) - ast::stmt_mac(*) | ast::stmt_semi(*) | ast::stmt_expr(*) => { - to_run.push(s); - } - } - } - result = do blk.node.expr.map_consume |e| { - do with_pp(intr) |pp, _| { pprust::print_expr(pp, e); } - }; - } - // return fast for empty inputs - if to_run.len() == 0 && result.is_none() { - return repl; - } - - // - // Stage 2: run everything up to typeck to learn the types of the new - // variables introduced into the program - // - info!("Learning about the new types in the program"); - repl.program.set_cache(); // before register_new_vars (which changes them) - let input = to_run.connect("\n"); - let test = repl.program.test_code(input, &result, *new_locals); - debug!("testing with ^^^^^^ %?", (||{ println(test) })()); - let dinput = driver::str_input(test.to_managed()); - let cfg = driver::build_configuration(sess, binary, &dinput); - let outputs = driver::build_output_filenames(&dinput, &None, &None, [], sess); - let (crate, tcx) = driver::compile_upto(sess, copy cfg, &dinput, - driver::cu_typeck, Some(outputs)); - // Once we're typechecked, record the types of all local variables defined - // in this input - do find_main(crate.expect("crate after cu_typeck"), sess) |blk| { - repl.program.register_new_vars(blk, tcx.expect("tcx after cu_typeck")); - } - - // - // Stage 3: Actually run the code in the JIT - // - info!("actually running code"); - let code = repl.program.code(input, &result); - debug!("actually running ^^^^^^ %?", (||{ println(code) })()); - let input = driver::str_input(code.to_managed()); - let cfg = driver::build_configuration(sess, binary, &input); - let outputs = driver::build_output_filenames(&input, &None, &None, [], sess); - let sess = driver::build_session(options, diagnostic::emit); - driver::compile_upto(sess, cfg, &input, driver::cu_everything, - Some(outputs)); - - // - // Stage 4: Inform the program that computation is done so it can update all - // local variable bindings. - // - info!("cleaning up after code"); - repl.program.consume_cache(); - - return repl; - - fn parse_input(sess: session::Session, binary: @str, - input: &str) -> @ast::crate { - let code = fmt!("fn main() {\n %s \n}", input); - let input = driver::str_input(code.to_managed()); - let cfg = driver::build_configuration(sess, binary, &input); - let outputs = driver::build_output_filenames(&input, &None, &None, [], sess); - let (crate, _) = driver::compile_upto(sess, cfg, &input, - driver::cu_parse, Some(outputs)); - crate.expect("parsing should return a crate") - } - - fn find_main(crate: @ast::crate, sess: session::Session, - f: &fn(&ast::blk)) { - for crate.node.module.items.iter().advance |item| { - match item.node { - ast::item_fn(_, _, _, _, ref blk) => { - if item.ident == sess.ident_of("main") { - return f(blk); - } - } - _ => {} - } - } - fail!("main function was expected somewhere..."); - } -} - -// Compiles a crate given by the filename as a library if the compiled -// version doesn't exist or is older than the source file. Binary is -// the name of the compiling executable. Returns Some(true) if it -// successfully compiled, Some(false) if the crate wasn't compiled -// because it already exists and is newer than the source file, or -// None if there were compile errors. -fn compile_crate(src_filename: ~str, binary: ~str) -> Option { - match do task::try { - let src_path = Path(src_filename); - let binary = binary.to_managed(); - let options = @session::options { - binary: binary, - addl_lib_search_paths: @mut ~[os::getcwd()], - .. copy *session::basic_options() - }; - let input = driver::file_input(copy src_path); - let sess = driver::build_session(options, diagnostic::emit); - *sess.building_library = true; - let cfg = driver::build_configuration(sess, binary, &input); - let outputs = driver::build_output_filenames( - &input, &None, &None, [], sess); - // If the library already exists and is newer than the source - // file, skip compilation and return None. - let mut should_compile = true; - let dir = os::list_dir_path(&Path(outputs.out_filename.dirname())); - let maybe_lib_path = do dir.iter().find_ |file| { - // The actual file's name has a hash value and version - // number in it which is unknown at this time, so looking - // for a file that matches out_filename won't work, - // instead we guess which file is the library by matching - // the prefix and suffix of out_filename to files in the - // directory. - let file_str = file.filename().get(); - file_str.starts_with(outputs.out_filename.filestem().get()) - && file_str.ends_with(outputs.out_filename.filetype().get()) - }; - match maybe_lib_path { - Some(lib_path) => { - let (src_mtime, _) = src_path.get_mtime().get(); - let (lib_mtime, _) = lib_path.get_mtime().get(); - if lib_mtime >= src_mtime { - should_compile = false; - } - }, - None => { }, - } - if (should_compile) { - println(fmt!("compiling %s...", src_filename)); - driver::compile_upto(sess, cfg, &input, driver::cu_everything, - Some(outputs)); - true - } else { false } - } { - Ok(true) => Some(true), - Ok(false) => Some(false), - Err(_) => None, - } -} - -/// Tries to get a line from rl after outputting a prompt. Returns -/// None if no input was read (e.g. EOF was reached). -fn get_line(use_rl: bool, prompt: &str) -> Option<~str> { - if use_rl { - let result = unsafe { rl::read(prompt) }; - - match result { - None => None, - Some(line) => { - unsafe { rl::add_history(line) }; - Some(line) - } - } - } else { - if io::stdin().eof() { - None - } else { - Some(io::stdin().read_line()) - } - } -} - -/// Run a command, e.g. :clear, :exit, etc. -fn run_cmd(repl: &mut Repl, _in: @io::Reader, _out: @io::Writer, - cmd: ~str, args: ~[~str], use_rl: bool) -> CmdAction { - let mut action = action_none; - match cmd { - ~"exit" => repl.running = false, - ~"clear" => { - repl.program.clear(); - - // XXX: Win32 version of linenoise can't do this - //rl::clear(); - } - ~"help" => { - println( - ":{\\n ..lines.. \\n:}\\n - execute multiline command\n\ - :load ... - loads given crates as dynamic libraries\n\ - :clear - clear the bindings\n\ - :exit - exit from the repl\n\ - :help - show this message"); - } - ~"load" => { - let mut loaded_crates: ~[~str] = ~[]; - for args.iter().advance |arg| { - let (crate, filename) = - if arg.ends_with(".rs") || arg.ends_with(".rc") { - (arg.slice_to(arg.len() - 3).to_owned(), copy *arg) - } else { - (copy *arg, *arg + ".rs") - }; - match compile_crate(filename, copy repl.binary) { - Some(_) => loaded_crates.push(crate), - None => { } - } - } - for loaded_crates.iter().advance |crate| { - let crate_path = Path(*crate); - let crate_dir = crate_path.dirname(); - repl.program.record_extern(fmt!("extern mod %s;", *crate)); - if !repl.lib_search_paths.iter().any_(|x| x == &crate_dir) { - repl.lib_search_paths.push(crate_dir); - } - } - if loaded_crates.is_empty() { - println("no crates loaded"); - } else { - println(fmt!("crates loaded: %s", - loaded_crates.connect(", "))); - } - } - ~"{" => { - let mut multiline_cmd = ~""; - let mut end_multiline = false; - while (!end_multiline) { - match get_line(use_rl, "rusti| ") { - None => fail!("unterminated multiline command :{ .. :}"), - Some(line) => { - if line.trim() == ":}" { - end_multiline = true; - } else { - multiline_cmd.push_str(line); - multiline_cmd.push_char('\n'); - } - } - } - } - action = action_run_line(multiline_cmd); - } - _ => println(~"unknown cmd: " + cmd) - } - return action; -} - -/// Executes a line of input, which may either be rust code or a -/// :command. Returns a new Repl if it has changed. -pub fn run_line(repl: &mut Repl, in: @io::Reader, out: @io::Writer, line: ~str, - use_rl: bool) - -> Option { - if line.starts_with(":") { - // drop the : and the \n (one byte each) - let full = line.slice(1, line.len()); - let split: ~[~str] = full.word_iter().transform(|s| s.to_owned()).collect(); - let len = split.len(); - - if len > 0 { - let cmd = copy split[0]; - - if !cmd.is_empty() { - let args = if len > 1 { - vec::slice(split, 1, len).to_owned() - } else { ~[] }; - - match run_cmd(repl, in, out, cmd, args, use_rl) { - action_none => { } - action_run_line(multiline_cmd) => { - if !multiline_cmd.is_empty() { - return run_line(repl, in, out, multiline_cmd, use_rl); - } - } - } - return None; - } - } - } - - let line = Cell::new(line); - let r = Cell::new(copy *repl); - let result = do task::try { - run(r.take(), line.take()) - }; - - if result.is_ok() { - return Some(result.get()); - } - return None; -} - -pub fn main() { - let args = os::args(); - let in = io::stdin(); - let out = io::stdout(); - let mut repl = Repl { - prompt: ~"rusti> ", - binary: copy args[0], - running: true, - lib_search_paths: ~[], - - program: Program::new(), - }; - - let istty = unsafe { libc::isatty(libc::STDIN_FILENO as i32) } != 0; - - // only print this stuff if the user is actually typing into rusti - if istty { - println("WARNING: The Rust REPL is experimental and may be"); - println("unstable. If you encounter problems, please use the"); - println("compiler instead. Type :help for help."); - - unsafe { - do rl::complete |line, suggest| { - if line.starts_with(":") { - suggest(~":clear"); - suggest(~":exit"); - suggest(~":help"); - suggest(~":load"); - } - } - } - } - - while repl.running { - match get_line(istty, repl.prompt) { - None => break, - Some(line) => { - if line.is_empty() { - if istty { - println("()"); - } - loop; - } - match run_line(&mut repl, in, out, line, istty) { - Some(new_repl) => repl = new_repl, - None => { } - } - } - } - } -} - -//#[cfg(test)] -#[cfg(ignore)] // FIXME #7541 doesn't work under cross-compile -mod tests { - use std::io; - use std::iterator::IteratorUtil; - use program::Program; - use super::*; - - fn repl() -> Repl { - Repl { - prompt: ~"rusti> ", - binary: ~"rusti", - running: true, - lib_search_paths: ~[], - program: Program::new(), - } - } - - fn run_program(prog: &str) { - let mut r = repl(); - for prog.split_iter('\n').advance |cmd| { - let result = run_line(&mut r, io::stdin(), io::stdout(), - cmd.to_owned(), false); - r = result.expect(fmt!("the command '%s' failed", cmd)); - } - } - - #[test] - // FIXME: #7220 rusti on 32bit mac doesn't work. - #[cfg(not(target_word_size="32", - target_os="macos"))] - fn run_all() { - // FIXME(#7071): - // By default, unit tests are run in parallel. Rusti, on the other hand, - // does not enjoy doing this. I suspect that it is because the LLVM - // bindings are not thread-safe (when running parallel tests, some tests - // were triggering assertions in LLVM (or segfaults). Hence, this - // function exists to run everything serially (sadface). - // - // To get some interesting output, run with RUST_LOG=rusti::tests - - debug!("hopefully this runs"); - run_program(""); - - debug!("regression test for #5937"); - run_program("use std::hashmap;"); - - debug!("regression test for #5784"); - run_program("let a = 3;"); - - // XXX: can't spawn new tasks because the JIT code is cleaned up - // after the main function is done. - // debug!("regression test for #5803"); - // run_program(" - // spawn( || println(\"Please don't segfault\") ); - // do spawn { println(\"Please?\"); } - // "); - - debug!("inferred integers are usable"); - run_program("let a = 2;\n()\n"); - run_program(" - let a = 3; - let b = 4u; - assert!((a as uint) + b == 7) - "); - - debug!("local variables can be shadowed"); - run_program(" - let a = 3; - let a = 5; - assert!(a == 5) - "); - - debug!("strings are usable"); - run_program(" - let a = ~\"\"; - let b = \"\"; - let c = @\"\"; - let d = a + b + c; - assert!(d.len() == 0); - "); - - debug!("vectors are usable"); - run_program(" - let a = ~[1, 2, 3]; - let b = &[1, 2, 3]; - let c = @[1, 2, 3]; - let d = a + b + c; - assert!(d.len() == 9); - let e: &[int] = []; - "); - - debug!("structs are usable"); - run_program(" - struct A{ a: int } - let b = A{ a: 3 }; - assert!(b.a == 3) - "); - - debug!("mutable variables"); - run_program(" - let mut a = 3; - a = 5; - let mut b = std::hashmap::HashSet::new::(); - b.insert(a); - assert!(b.contains(&5)) - assert!(b.len() == 1) - "); - - debug!("functions are cached"); - run_program(" - fn fib(x: int) -> int { if x < 2 {x} else { fib(x - 1) + fib(x - 2) } } - let a = fib(3); - let a = a + fib(4); - assert!(a == 5) - "); - - debug!("modules are cached"); - run_program(" - mod b { pub fn foo() -> uint { 3 } } - assert!(b::foo() == 3) - "); - - debug!("multiple function definitions are allowed"); - run_program(" - fn f() {} - fn f() {} - f() - "); - - debug!("multiple item definitions are allowed"); - run_program(" - fn f() {} - mod f {} - struct f; - enum f {} - fn f() {} - f() - "); - } - - #[test] - // FIXME: #7220 rusti on 32bit mac doesn't work. - #[cfg(not(target_word_size="32", - target_os="macos"))] - fn exit_quits() { - let mut r = repl(); - assert!(r.running); - let result = run_line(&mut r, io::stdin(), io::stdout(), - ~":exit", false); - assert!(result.is_none()); - assert!(!r.running); - } -} diff --git a/src/librusti/rusti.rs b/src/librusti/rusti.rs index f91d99322390..bdbbcfc2b665 100644 --- a/src/librusti/rusti.rs +++ b/src/librusti/rusti.rs @@ -511,8 +511,7 @@ pub fn main() { } } -//#[cfg(test)] -#[cfg(ignore)] // FIXME #7541 doesn't work under cross-compile +#[cfg(test)] mod tests { use std::io; use std::iterator::IteratorUtil; @@ -530,8 +529,8 @@ mod tests { } // FIXME: #7220 rusti on 32bit mac doesn't work. + // FIXME: #7641 rusti on 32bit linux cross compile doesn't work #[cfg(not(target_word_size="32"))] - #[cfg(not(target_os="macos"))] fn run_program(prog: &str) { let mut r = repl(); for prog.split_iter('\n').advance |cmd| { @@ -540,7 +539,7 @@ mod tests { r = result.expect(fmt!("the command '%s' failed", cmd)); } } - #[cfg(target_word_size="32", target_os="macos")] + #[cfg(target_word_size="32")] fn run_program(_: &str) {} #[test] From 2f27d4316663dfecd47396d3655458602df28d29 Mon Sep 17 00:00:00 2001 From: Jed Davis Date: Wed, 13 Mar 2013 23:28:12 -0700 Subject: [PATCH 19/93] GC static_size_of_enum, which was unused --- src/librustc/middle/trans/machine.rs | 42 ---------------------------- src/librustc/middle/trans/type_of.rs | 3 +- 2 files changed, 1 insertion(+), 44 deletions(-) diff --git a/src/librustc/middle/trans/machine.rs b/src/librustc/middle/trans/machine.rs index f55523b28418..2cd313ff4315 100644 --- a/src/librustc/middle/trans/machine.rs +++ b/src/librustc/middle/trans/machine.rs @@ -14,9 +14,6 @@ use lib::llvm::{ValueRef}; use lib::llvm::False; use lib::llvm::llvm; use middle::trans::common::*; -use middle::trans::type_of; -use middle::ty; -use util::ppaux::ty_to_str; use middle::trans::type_::Type; @@ -116,42 +113,3 @@ pub fn llalign_of(cx: &CrateContext, ty: Type) -> ValueRef { llvm::LLVMAlignOf(ty.to_ref()), cx.int_type.to_ref(), False); } } - -// Computes the size of the data part of an enum. -pub fn static_size_of_enum(cx: &mut CrateContext, t: ty::t) -> uint { - if cx.enum_sizes.contains_key(&t) { - return cx.enum_sizes.get_copy(&t); - } - - debug!("static_size_of_enum %s", ty_to_str(cx.tcx, t)); - - match ty::get(t).sty { - ty::ty_enum(tid, ref substs) => { - // Compute max(variant sizes). - let mut max_size = 0; - let variants = ty::enum_variants(cx.tcx, tid); - for variants.iter().advance |variant| { - if variant.args.len() == 0 { - loop; - } - - let lltypes = variant.args.map(|&variant_arg| { - let substituted = ty::subst(cx.tcx, substs, variant_arg); - type_of::sizing_type_of(cx, substituted) - }); - - debug!("static_size_of_enum: variant %s type %s", - cx.tcx.sess.str_of(variant.name), - cx.tn.type_to_str(Type::struct_(lltypes, false))); - - let this_size = llsize_of_real(cx, Type::struct_(lltypes, false)); - if max_size < this_size { - max_size = this_size; - } - } - cx.enum_sizes.insert(t, max_size); - return max_size; - } - _ => cx.sess.bug("static_size_of_enum called on non-enum") - } -} diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index 481f08ee192d..47ce0b7c2280 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -104,8 +104,7 @@ pub fn type_of_non_gc_box(cx: &mut CrateContext, t: ty::t) -> Type { // // (2) It won't make any recursive calls to determine the structure of the // type behind pointers. This can help prevent infinite loops for -// recursive types. For example, `static_size_of_enum()` relies on this -// behavior. +// recursive types. For example, enum types rely on this behavior. pub fn sizing_type_of(cx: &mut CrateContext, t: ty::t) -> Type { match cx.llsizingtypes.find_copy(&t) { From 863e75f0a1f70494a8a036d35e8358748fb963a3 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 30 Jun 2013 20:12:57 -0400 Subject: [PATCH 20/93] Fixed documentation for finalize->drop change --- doc/rust.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/rust.md b/doc/rust.md index c61cbe6476ce..0b413783c35c 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -2876,13 +2876,13 @@ The kinds are: Types with destructors (types that implement `Drop`) can not implement `Copy`. `Drop` : This is not strictly a kind, but its presence interacts with kinds: the `Drop` - trait provides a single method `finalize` that takes no parameters, and is run + trait provides a single method `drop` that takes no parameters, and is run when values of the type are dropped. Such a method is called a "destructor", and are always executed in "top-down" order: a value is completely destroyed before any of the values it owns run their destructors. Only `Send` types that do not implement `Copy` can implement `Drop`. -> **Note:** The `finalize` method may be renamed in future versions of Rust. +> **Note:** The `drop` method may be renamed in future versions of Rust. _Default_ : Types with destructors, closure environments, From c63b3f8e285b39349f198eca15ec252a2c8938db Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 30 Jun 2013 20:18:34 -0400 Subject: [PATCH 21/93] Removing the rename warning Now that the finalize->drop rename has happened, this hopefully shouldn't end up changing again. --- doc/rust.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/doc/rust.md b/doc/rust.md index 0b413783c35c..b23efe773ebe 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -2882,8 +2882,6 @@ The kinds are: before any of the values it owns run their destructors. Only `Send` types that do not implement `Copy` can implement `Drop`. -> **Note:** The `drop` method may be renamed in future versions of Rust. - _Default_ : Types with destructors, closure environments, and various other _non-first-class_ types, From 866a5b1c78e52bd5c1c34df4a1a3c363ad6bfe7c Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 2 Jul 2013 23:34:35 +0200 Subject: [PATCH 22/93] Added support for struct-like enum variants in middle::ty::enum_variants(). --- src/librustc/middle/ty.rs | 57 ++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index bbf548d2659a..8c70c6204768 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3816,41 +3816,62 @@ pub fn enum_variants(cx: ctxt, id: ast::def_id) -> @~[VariantInfo] { }, _) => { let mut disr_val = -1; @enum_definition.variants.iter().transform(|variant| { + + let ctor_ty = node_id_to_type(cx, variant.node.id); + match variant.node.kind { ast::tuple_variant_kind(ref args) => { - let ctor_ty = node_id_to_type(cx, variant.node.id); - let arg_tys = { - if args.len() > 0u { - ty_fn_args(ctor_ty).map(|a| *a) - } else { + let arg_tys = if args.len() > 0u { + ty_fn_args(ctor_ty).map(|a| *a) } + else { ~[] - } - }; + }; + match variant.node.disr_expr { Some (ex) => { disr_val = match const_eval::eval_const_expr(cx, ex) { const_eval::const_int(val) => val as int, - _ => cx.sess.bug("tag_variants: bad disr expr") + _ => cx.sess.bug("enum_variants: bad disr expr") } } _ => disr_val += 1 } - @VariantInfo_{args: arg_tys, - ctor_ty: ctor_ty, - name: variant.node.name, - id: ast_util::local_def(variant.node.id), - disr_val: disr_val, - vis: variant.node.vis + @VariantInfo_{ + args: arg_tys, + ctor_ty: ctor_ty, + name: variant.node.name, + id: ast_util::local_def(variant.node.id), + disr_val: disr_val, + vis: variant.node.vis } - } - ast::struct_variant_kind(_) => { - fail!("struct variant kinds unimpl in enum_variants") + }, + ast::struct_variant_kind(struct_def) => { + let arg_tys = + // Is this check needed for structs too, or are they always guaranteed + // to have a valid constructor function? + if struct_def.fields.len() > 0 { + ty_fn_args(ctor_ty).map(|a| *a) + } else { + ~[] + }; + + assert!(variant.node.disr_expr.is_none()); + disr_val += 1; + + @VariantInfo_{ + args: arg_tys, + ctor_ty: ctor_ty, + name: variant.node.name, + id: ast_util::local_def(variant.node.id), + disr_val: disr_val, + vis: variant.node.vis + } } } }).collect() } - _ => cx.sess.bug("tag_variants: id not bound to an enum") + _ => cx.sess.bug("enum_variants: id not bound to an enum") } }; cx.enum_var_cache.insert(id, result); From 6ee8fee730b5a0ae20ee0968d87a1597908a62ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Wed, 3 Jul 2013 14:56:26 +0200 Subject: [PATCH 23/93] vec: Fix size_hint() of reverse iterators Fixes #7558 --- src/libstd/vec.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 02eadaed5e89..f12e00bfa0a4 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -2125,7 +2125,12 @@ macro_rules! iterator { #[inline] fn size_hint(&self) -> (Option, Option) { - let exact = Some(((self.end as uint) - (self.ptr as uint)) / size_of::<$elem>()); + let diff = if $step > 0 { + (self.end as uint) - (self.ptr as uint) + } else { + (self.ptr as uint) - (self.end as uint) + }; + let exact = Some(diff / size_of::<$elem>()); (exact, exact) } } @@ -3404,6 +3409,16 @@ mod tests { assert!(it.next().is_none()); } + #[test] + fn test_iter_size_hints() { + use iterator::*; + let mut xs = [1, 2, 5, 10, 11]; + assert_eq!(xs.iter().size_hint(), (Some(5), Some(5))); + assert_eq!(xs.rev_iter().size_hint(), (Some(5), Some(5))); + assert_eq!(xs.mut_iter().size_hint(), (Some(5), Some(5))); + assert_eq!(xs.mut_rev_iter().size_hint(), (Some(5), Some(5))); + } + #[test] fn test_mut_iterator() { use iterator::*; From eee677564216a64f48ebaffa860e4062f2b2d264 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Tue, 2 Jul 2013 01:26:44 +1000 Subject: [PATCH 24/93] Implement consuming iterators for ~[], remove vec::{consume, consume_reverse, map_consume}. --- doc/tutorial-container.md | 2 +- src/libextra/json.rs | 5 +- src/libextra/par.rs | 5 +- src/libextra/test.rs | 2 +- src/librustc/back/link.rs | 2 +- src/librustc/driver/driver.rs | 4 +- src/librustc/middle/lint.rs | 3 +- src/libstd/at_vec.rs | 5 +- src/libstd/either.rs | 2 +- src/libstd/hashmap.rs | 7 +- src/libstd/vec.rs | 220 ++++++++++-------------- src/libsyntax/ext/fmt.rs | 3 +- src/test/bench/graph500-bfs.rs | 4 +- src/test/bench/task-perf-one-million.rs | 17 +- 14 files changed, 123 insertions(+), 158 deletions(-) diff --git a/doc/tutorial-container.md b/doc/tutorial-container.md index 66bd0b9c1319..5ed61d693014 100644 --- a/doc/tutorial-container.md +++ b/doc/tutorial-container.md @@ -108,7 +108,7 @@ impl Iterator for ZeroStream { ## Container iterators Containers implement iteration over the contained elements by returning an -iterator object. For example, vectors have four iterators available: +iterator object. For example, vector slices have four iterators available: * `vector.iter()`, for immutable references to the elements * `vector.mut_iter()`, for mutable references to the elements diff --git a/src/libextra/json.rs b/src/libextra/json.rs index 210921aa3d76..71d99479693f 100644 --- a/src/libextra/json.rs +++ b/src/libextra/json.rs @@ -24,7 +24,6 @@ use std::io::{WriterUtil, ReaderUtil}; use std::io; use std::str; use std::to_str; -use std::vec; use serialize::Encodable; use serialize; @@ -941,7 +940,7 @@ impl serialize::Decoder for Decoder { let name = match self.stack.pop() { String(s) => s, List(list) => { - do vec::consume_reverse(list) |_i, v| { + for list.consume_rev_iter().advance |v| { self.stack.push(v); } match self.stack.pop() { @@ -1059,7 +1058,7 @@ impl serialize::Decoder for Decoder { let len = match self.stack.pop() { List(list) => { let len = list.len(); - do vec::consume_reverse(list) |_i, v| { + for list.consume_rev_iter().advance |v| { self.stack.push(v); } len diff --git a/src/libextra/par.rs b/src/libextra/par.rs index 2d8273656815..da046f6b5ce7 100644 --- a/src/libextra/par.rs +++ b/src/libextra/par.rs @@ -78,11 +78,10 @@ fn map_slices( info!("num_tasks: %?", (num_tasks, futures.len())); assert_eq!(num_tasks, futures.len()); - let r = do vec::map_consume(futures) |ys| { + do futures.consume_iter().transform |ys| { let mut ys = ys; ys.get() - }; - r + }.collect() } } diff --git a/src/libextra/test.rs b/src/libextra/test.rs index 59aed0055d87..313577ac67dd 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -477,7 +477,7 @@ fn run_tests(opts: &TestOpts, } // All benchmarks run at the end, in serial. - do vec::consume(filtered_benchs) |_, b| { + for filtered_benchs.consume_iter().advance |b| { callback(TeWait(copy b.desc)); run_test(!opts.run_benchmarks, b, ch.clone()); let (test, result) = p.recv(); diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 61d39421b7fd..a7abc6190803 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -893,7 +893,7 @@ pub fn link_args(sess: Session, // Add all the link args for external crates. do cstore::iter_crate_data(cstore) |crate_num, _| { let link_args = csearch::get_link_args_for_crate(cstore, crate_num); - do vec::consume(link_args) |_, link_arg| { + for link_args.consume_iter().advance |link_arg| { args.push(link_arg); } } diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index a32f54fe7bba..3c5075474488 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -123,10 +123,10 @@ pub fn build_configuration(sess: Session, argv0: @str, input: &input) -> // Convert strings provided as --cfg [cfgspec] into a crate_cfg fn parse_cfgspecs(cfgspecs: ~[~str], demitter: diagnostic::Emitter) -> ast::crate_cfg { - do vec::map_consume(cfgspecs) |s| { + do cfgspecs.consume_iter().transform |s| { let sess = parse::new_parse_sess(Some(demitter)); parse::parse_meta_from_source_str(@"cfgspec", s.to_managed(), ~[], sess) - } + }.collect() } pub enum input { diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index e345a9d703c9..ce9ab790b11b 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -24,7 +24,6 @@ use std::u16; use std::u32; use std::u64; use std::u8; -use std::vec; use extra::smallintmap::SmallIntMap; use syntax::attr; use syntax::codemap::span; @@ -987,7 +986,7 @@ fn lint_session() -> visit::vt<@mut Context> { match cx.tcx.sess.lints.pop(&id) { None => {}, Some(l) => { - do vec::consume(l) |_, (lint, span, msg)| { + for l.consume_iter().advance |(lint, span, msg)| { cx.span_lint(lint, span, msg) } } diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs index 325ce097cd5a..cadd58118edc 100644 --- a/src/libstd/at_vec.rs +++ b/src/libstd/at_vec.rs @@ -17,8 +17,7 @@ use kinds::Copy; use option::Option; use sys; use uint; -use vec; -use vec::ImmutableVector; +use vec::{ImmutableVector, OwnedVector}; /// Code for dealing with @-vectors. This is pretty incomplete, and /// contains a bunch of duplication from the code for ~-vectors. @@ -159,7 +158,7 @@ pub fn to_managed_consume(v: ~[T]) -> @[T] { let mut av = @[]; unsafe { raw::reserve(&mut av, v.len()); - do vec::consume(v) |_i, x| { + for v.consume_iter().advance |x| { raw::push(&mut av, x); } transmute(av) diff --git a/src/libstd/either.rs b/src/libstd/either.rs index b6da93f9d40a..8b9b3102831c 100644 --- a/src/libstd/either.rs +++ b/src/libstd/either.rs @@ -73,7 +73,7 @@ pub fn rights(eithers: &[Either]) -> ~[U] { pub fn partition(eithers: ~[Either]) -> (~[T], ~[U]) { let mut lefts: ~[T] = ~[]; let mut rights: ~[U] = ~[]; - do vec::consume(eithers) |_i, elt| { + for eithers.consume_iter().advance |elt| { match elt { Left(l) => lefts.push(l), Right(r) => rights.push(r) diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index 85dca1154bc0..2d80dc2be152 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -24,7 +24,7 @@ use rand::RngUtil; use rand; use uint; use vec; -use vec::{ImmutableVector, MutableVector}; +use vec::{ImmutableVector, MutableVector, OwnedVector}; use kinds::Copy; use util::{replace, unreachable}; @@ -175,7 +175,8 @@ impl HashMap { vec::from_fn(new_capacity, |_| None)); self.size = 0; - do vec::consume(old_buckets) |_, bucket| { + // consume_rev_iter is more efficient + for old_buckets.consume_rev_iter().advance |bucket| { self.insert_opt_bucket(bucket); } } @@ -441,7 +442,7 @@ impl HashMap { vec::from_fn(INITIAL_CAPACITY, |_| None)); self.size = 0; - do vec::consume(buckets) |_, bucket| { + for buckets.consume_iter().advance |bucket| { match bucket { None => {}, Some(Bucket{key, value, _}) => { diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 28532bd54e36..3fa9df2a9e0d 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -277,67 +277,6 @@ pub fn rsplitn(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] { result } -/// Consumes all elements, in a vector, moving them out into the / closure -/// provided. The vector is traversed from the start to the end. -/// -/// This method does not impose any requirements on the type of the vector being -/// consumed, but it prevents any usage of the vector after this function is -/// called. -/// -/// # Examples -/// -/// ~~~ {.rust} -/// let v = ~[~"a", ~"b"]; -/// do vec::consume(v) |i, s| { -/// // s has type ~str, not &~str -/// io::println(s + fmt!(" %d", i)); -/// } -/// ~~~ -pub fn consume(mut v: ~[T], f: &fn(uint, v: T)) { - unsafe { - do as_mut_buf(v) |p, ln| { - for uint::range(0, ln) |i| { - // NB: This unsafe operation counts on init writing 0s to the - // holes we create in the vector. That ensures that, if the - // iterator fails then we won't try to clean up the consumed - // elements during unwinding - let x = intrinsics::init(); - let p = ptr::mut_offset(p, i); - f(i, ptr::replace_ptr(p, x)); - } - } - - raw::set_len(&mut v, 0); - } -} - -/// Consumes all elements, in a vector, moving them out into the / closure -/// provided. The vectors is traversed in reverse order (from end to start). -/// -/// This method does not impose any requirements on the type of the vector being -/// consumed, but it prevents any usage of the vector after this function is -/// called. -pub fn consume_reverse(mut v: ~[T], f: &fn(uint, v: T)) { - unsafe { - do as_mut_buf(v) |p, ln| { - let mut i = ln; - while i > 0 { - i -= 1; - - // NB: This unsafe operation counts on init writing 0s to the - // holes we create in the vector. That ensures that, if the - // iterator fails then we won't try to clean up the consumed - // elements during unwinding - let x = intrinsics::init(); - let p = ptr::mut_offset(p, i); - f(i, ptr::replace_ptr(p, x)); - } - } - - raw::set_len(&mut v, 0); - } -} - // Appending /// Iterates over the `rhs` vector, copying each element and appending it to the @@ -360,20 +299,6 @@ pub fn append_one(lhs: ~[T], x: T) -> ~[T] { // Functional utilities -/// Consumes a vector, mapping it into a different vector. This function takes -/// ownership of the supplied vector `v`, moving each element into the closure -/// provided to generate a new element. The vector of new elements is then -/// returned. -/// -/// The original vector `v` cannot be used after this function call (it is moved -/// inside), but there are no restrictions on the type of the vector. -pub fn map_consume(v: ~[T], f: &fn(v: T) -> U) -> ~[U] { - let mut result = ~[]; - do consume(v) |_i, x| { - result.push(f(x)); - } - result -} /** * Apply a function to each element of a vector and return a concatenation * of each result vector @@ -396,7 +321,7 @@ pub fn filter_map( */ let mut result = ~[]; - do consume(v) |_, elem| { + for v.consume_iter().advance |elem| { match f(elem) { None => {} Some(result_elem) => { result.push(result_elem); } @@ -434,9 +359,7 @@ pub fn filter_mapped( */ pub fn filter(v: ~[T], f: &fn(t: &T) -> bool) -> ~[T] { let mut result = ~[]; - // FIXME (#4355 maybe): using v.consume here crashes - // do v.consume |_, elem| { - do consume(v) |_, elem| { + for v.consume_iter().advance |elem| { if f(&elem) { result.push(elem); } } result @@ -542,7 +465,7 @@ pub fn unzip_slice(v: &[(T, U)]) -> (~[T], ~[U]) { pub fn unzip(v: ~[(T, U)]) -> (~[T], ~[U]) { let mut ts = ~[]; let mut us = ~[]; - do consume(v) |_i, p| { + for v.consume_iter().advance |p| { let (t, u) = p; ts.push(t); us.push(u); @@ -1202,6 +1125,9 @@ impl<'self,T:Copy> ImmutableCopyableVector for &'self [T] { #[allow(missing_doc)] pub trait OwnedVector { + fn consume_iter(self) -> VecConsumeIterator; + fn consume_rev_iter(self) -> VecConsumeRevIterator; + fn reserve(&mut self, n: uint); fn reserve_at_least(&mut self, n: uint); fn capacity(&self) -> uint; @@ -1218,14 +1144,38 @@ pub trait OwnedVector { fn swap_remove(&mut self, index: uint) -> T; fn truncate(&mut self, newlen: uint); fn retain(&mut self, f: &fn(t: &T) -> bool); - fn consume(self, f: &fn(uint, v: T)); - fn consume_reverse(self, f: &fn(uint, v: T)); fn filter(self, f: &fn(t: &T) -> bool) -> ~[T]; fn partition(self, f: &fn(&T) -> bool) -> (~[T], ~[T]); fn grow_fn(&mut self, n: uint, op: &fn(uint) -> T); } impl OwnedVector for ~[T] { + /// Creates a consuming iterator, that is, one that moves each + /// value out of the vector (from start to end). The vector cannot + /// be used after calling this. + /// + /// Note that this performs O(n) swaps, and so `consume_rev_iter` + /// (which just calls `pop` repeatedly) is more efficient. + /// + /// # Examples + /// + /// ~~~ {.rust} + /// let v = ~[~"a", ~"b"]; + /// for v.consume_iter().advance |s| { + /// // s has type ~str, not &~str + /// println(s); + /// } + /// ~~~ + fn consume_iter(self) -> VecConsumeIterator { + VecConsumeIterator { v: self, idx: 0 } + } + /// Creates a consuming iterator that moves out of the vector in + /// reverse order. Also see `consume_iter`, however note that this + /// is more efficient. + fn consume_rev_iter(self) -> VecConsumeRevIterator { + VecConsumeRevIterator { v: self } + } + /** * Reserves capacity for exactly `n` elements in the given vector. * @@ -1532,16 +1482,6 @@ impl OwnedVector for ~[T] { } } - #[inline] - fn consume(self, f: &fn(uint, v: T)) { - consume(self, f) - } - - #[inline] - fn consume_reverse(self, f: &fn(uint, v: T)) { - consume_reverse(self, f) - } - #[inline] fn filter(self, f: &fn(&T) -> bool) -> ~[T] { filter(self, f) @@ -1556,7 +1496,7 @@ impl OwnedVector for ~[T] { let mut lefts = ~[]; let mut rights = ~[]; - do self.consume |_, elt| { + for self.consume_iter().advance |elt| { if f(&elt) { lefts.push(elt); } else { @@ -2132,7 +2072,7 @@ macro_rules! iterator { } //iterator!{struct VecIterator -> *T, &'self T} -/// An iterator for iterating over a vector +/// An iterator for iterating over a vector. pub struct VecIterator<'self, T> { priv ptr: *T, priv end: *T, @@ -2141,7 +2081,7 @@ pub struct VecIterator<'self, T> { iterator!{impl VecIterator -> &'self T, 1} //iterator!{struct VecRevIterator -> *T, &'self T} -/// An iterator for iterating over a vector in reverse +/// An iterator for iterating over a vector in reverse. pub struct VecRevIterator<'self, T> { priv ptr: *T, priv end: *T, @@ -2150,7 +2090,7 @@ pub struct VecRevIterator<'self, T> { iterator!{impl VecRevIterator -> &'self T, -1} //iterator!{struct VecMutIterator -> *mut T, &'self mut T} -/// An iterator for mutating the elements of a vector +/// An iterator for mutating the elements of a vector. pub struct VecMutIterator<'self, T> { priv ptr: *mut T, priv end: *mut T, @@ -2159,7 +2099,7 @@ pub struct VecMutIterator<'self, T> { iterator!{impl VecMutIterator -> &'self mut T, 1} //iterator!{struct VecMutRevIterator -> *mut T, &'self mut T} -/// An iterator for mutating the elements of a vector in reverse +/// An iterator for mutating the elements of a vector in reverse. pub struct VecMutRevIterator<'self, T> { priv ptr: *mut T, priv end: *mut T, @@ -2167,6 +2107,49 @@ pub struct VecMutRevIterator<'self, T> { } iterator!{impl VecMutRevIterator -> &'self mut T, -1} +/// An iterator that moves out of a vector. +pub struct VecConsumeIterator { + priv v: ~[T], + priv idx: uint, +} + +impl Iterator for VecConsumeIterator { + fn next(&mut self) -> Option { + // this is peculiar, but is required for safety with respect + // to dtors. It traverses the first half of the vec, and + // removes them by swapping them with the last element (and + // popping), which results in the second half in reverse + // order, and so these can just be pop'd off. That is, + // + // [1,2,3,4,5] => 1, [5,2,3,4] => 2, [5,4,3] => 3, [5,4] => 4, + // [5] -> 5, [] + + if self.v.is_empty() { + None + } else { + let l = self.v.len(); + if self.idx < l { + self.v.swap(self.idx, l - 1); + self.idx += 1; + } + + Some(self.v.pop()) + } + } +} + +/// An iterator that moves out of a vector in reverse order. +pub struct VecConsumeRevIterator { + priv v: ~[T] +} + +impl Iterator for VecConsumeRevIterator { + fn next(&mut self) -> Option { + if self.v.is_empty() { None } + else { Some(self.v.pop()) } + } +} + #[cfg(stage0)] impl> FromIterator for ~[A] { pub fn from_iterator(iterator: &mut T) -> ~[A] { @@ -3200,20 +3183,6 @@ mod tests { }; } - #[test] - #[ignore(windows)] - #[should_fail] - fn test_consume_fail() { - let v = ~[(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do consume(v) |_i, _elt| { - if i == 2 { - fail!() - } - i += 1; - }; - } - #[test] #[ignore(windows)] #[should_fail] @@ -3243,21 +3212,6 @@ mod tests { }; } - #[test] - #[ignore(windows)] - #[should_fail] - fn test_map_consume_fail() { - let v = ~[(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do map_consume(v) |_elt| { - if i == 2 { - fail!() - } - i += 0; - ~[(~0, @0)] - }; - } - #[test] #[ignore(windows)] #[should_fail] @@ -3428,6 +3382,20 @@ mod tests { assert_eq!(xs, [5, 5, 5, 5, 5]) } + #[test] + fn test_consume_iterator() { + use iterator::*; + let xs = ~[1u,2,3,4,5]; + assert_eq!(xs.consume_iter().fold(0, |a: uint, b: uint| 10*a + b), 12345); + } + + #[test] + fn test_consume_rev_iterator() { + use iterator::*; + let xs = ~[1u,2,3,4,5]; + assert_eq!(xs.consume_rev_iter().fold(0, |a: uint, b: uint| 10*a + b), 54321); + } + #[test] fn test_move_from() { let mut a = [1,2,3,4,5]; diff --git a/src/libsyntax/ext/fmt.rs b/src/libsyntax/ext/fmt.rs index 76073199f645..333570b6c9d7 100644 --- a/src/libsyntax/ext/fmt.rs +++ b/src/libsyntax/ext/fmt.rs @@ -22,7 +22,6 @@ use ext::build::AstBuilder; use std::option; use std::unstable::extfmt::ct::*; -use std::vec; use parse::token::{str_to_ident}; pub fn expand_syntax_ext(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree]) @@ -268,7 +267,7 @@ fn pieces_to_expr(cx: @ExtCtxt, sp: span, corresponding function in std::unstable::extfmt. Each function takes a buffer to insert data into along with the data being formatted. */ let npieces = pieces.len(); - do vec::consume(pieces) |i, pc| { + for pieces.consume_iter().enumerate().advance |(i, pc)| { match pc { /* Raw strings get appended via str::push_str */ PieceString(s) => { diff --git a/src/test/bench/graph500-bfs.rs b/src/test/bench/graph500-bfs.rs index bc5efc5fca1f..d327b73c625e 100644 --- a/src/test/bench/graph500-bfs.rs +++ b/src/test/bench/graph500-bfs.rs @@ -95,13 +95,13 @@ fn make_graph(N: uint, edges: ~[(node_id, node_id)]) -> graph { } } - do vec::map_consume(graph) |mut v| { + do graph.consume_iter().transform |mut v| { let mut vec = ~[]; do v.consume |i| { vec.push(i); } vec - } + }.collect() } fn gen_search_keys(graph: &[~[node_id]], n: uint) -> ~[node_id] { diff --git a/src/test/bench/task-perf-one-million.rs b/src/test/bench/task-perf-one-million.rs index e1366a3a8694..1cd90962c5b7 100644 --- a/src/test/bench/task-perf-one-million.rs +++ b/src/test/bench/task-perf-one-million.rs @@ -28,20 +28,21 @@ fn calc(children: uint, parent_wait_chan: &Chan>>) { wait_port }; - let child_start_chans: ~[Chan>] = vec::map_consume(wait_ports, |port| port.recv()); + let child_start_chans: ~[Chan>] = + wait_ports.consume_iter().transform(|port| port.recv()).collect(); let (start_port, start_chan) = stream::>(); parent_wait_chan.send(start_chan); let parent_result_chan: Chan = start_port.recv(); - let child_sum_ports: ~[Port] = do vec::map_consume(child_start_chans) |child_start_chan| { - let (child_sum_port, child_sum_chan) = stream::(); - child_start_chan.send(child_sum_chan); - child_sum_port - }; + let child_sum_ports: ~[Port] = + do child_start_chans.consume_iter().transform |child_start_chan| { + let (child_sum_port, child_sum_chan) = stream::(); + child_start_chan.send(child_sum_chan); + child_sum_port + }.collect(); - let mut sum = 0; - vec::consume(child_sum_ports, |_, sum_port| sum += sum_port.recv() ); + let sum = child_sum_ports.consume_iter().fold(0, |sum, sum_port| sum + sum_port.recv() ); parent_result_chan.send(sum + 1); } From de0d696561a381e182c792acbe8f608c8be94c3b Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Tue, 2 Jul 2013 12:38:19 +1000 Subject: [PATCH 25/93] Remove vec::{filter, filtered, filter_map, filter_mapped}, replaced by iterators. --- src/libextra/test.rs | 8 +- src/librustc/front/config.rs | 54 +++-- src/librustc/front/test.rs | 16 +- src/librustc/middle/astencode.rs | 12 +- src/librustc/middle/check_match.rs | 10 +- src/librustc/middle/trans/controlflow.rs | 11 +- src/librustdoc/attr_parser.rs | 6 +- src/librustdoc/doc.rs | 143 ++++-------- src/librustdoc/extract.rs | 5 +- src/librustdoc/page_pass.rs | 9 +- src/librustdoc/prune_hidden_pass.rs | 6 +- src/librustdoc/prune_private_pass.rs | 14 +- src/librustpkg/util.rs | 6 +- src/librustpkg/workspace.rs | 5 +- src/libstd/os.rs | 6 +- src/libstd/vec.rs | 215 ------------------- src/libsyntax/ast_util.rs | 4 +- src/libsyntax/attr.rs | 13 +- src/libsyntax/fold.rs | 4 +- src/test/compile-fail/lint-unused-imports.rs | 2 +- 20 files changed, 131 insertions(+), 418 deletions(-) diff --git a/src/libextra/test.rs b/src/libextra/test.rs index 313577ac67dd..97793ce440c2 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -523,7 +523,7 @@ pub fn filter_tests( } else { return option::None; } } - vec::filter_map(filtered, |x| filter_fn(x, filter_str)) + filtered.consume_iter().filter_map(|x| filter_fn(x, filter_str)).collect() }; // Maybe pull out the ignored test and unignore them @@ -541,7 +541,7 @@ pub fn filter_tests( None } }; - vec::filter_map(filtered, |x| filter(x)) + filtered.consume_iter().filter_map(|x| filter(x)).collect() }; // Sort the tests alphabetically @@ -720,9 +720,9 @@ impl BenchHarness { // Eliminate outliers let med = samples.median(); let mad = samples.median_abs_dev(); - let samples = do vec::filter(samples) |f| { + let samples = do samples.consume_iter().filter |f| { num::abs(*f - med) <= 3.0 * mad - }; + }.collect::<~[f64]>(); debug!("%u samples, median %f, MAD=%f, %u survived filter", n_samples, med as float, mad as float, diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs index b1d4820f062e..7d478afee41a 100644 --- a/src/librustc/front/config.rs +++ b/src/librustc/front/config.rs @@ -10,7 +10,6 @@ use std::option; -use std::vec; use syntax::{ast, fold, attr}; type in_cfg_pred = @fn(attrs: ~[ast::attribute]) -> bool; @@ -61,13 +60,15 @@ fn filter_view_item(cx: @Context, view_item: @ast::view_item } fn fold_mod(cx: @Context, m: &ast::_mod, fld: @fold::ast_fold) -> ast::_mod { - let filtered_items = - m.items.filter_mapped(|a| filter_item(cx, *a)); - let filtered_view_items = - m.view_items.filter_mapped(|a| filter_view_item(cx, *a)); + let filtered_items = do m.items.iter().filter_map |a| { + filter_item(cx, *a).chain(|x| fld.fold_item(x)) + }.collect(); + let filtered_view_items = do m.view_items.iter().filter_map |a| { + filter_view_item(cx, *a).map(|x| fld.fold_view_item(*x)) + }.collect(); ast::_mod { - view_items: filtered_view_items.map(|x| fld.fold_view_item(*x)), - items: vec::filter_map(filtered_items, |x| fld.fold_item(x)) + view_items: filtered_view_items, + items: filtered_items } } @@ -83,14 +84,14 @@ fn fold_foreign_mod( nm: &ast::foreign_mod, fld: @fold::ast_fold ) -> ast::foreign_mod { - let filtered_items = - nm.items.filter_mapped(|a| filter_foreign_item(cx, *a)); - let filtered_view_items = - nm.view_items.filter_mapped(|a| filter_view_item(cx, *a)); + let filtered_items = nm.items.iter().filter_map(|a| filter_foreign_item(cx, *a)).collect(); + let filtered_view_items = do nm.view_items.iter().filter_map |a| { + filter_view_item(cx, *a).map(|x| fld.fold_view_item(*x)) + }.collect(); ast::foreign_mod { sort: nm.sort, abis: nm.abis, - view_items: filtered_view_items.iter().transform(|x| fld.fold_view_item(*x)).collect(), + view_items: filtered_view_items, items: filtered_items } } @@ -99,11 +100,13 @@ fn fold_item_underscore(cx: @Context, item: &ast::item_, fld: @fold::ast_fold) -> ast::item_ { let item = match *item { ast::item_impl(ref a, b, c, ref methods) => { - let methods = methods.filtered(|m| method_in_cfg(cx, *m) ); + let methods = methods.iter().filter(|m| method_in_cfg(cx, **m)) + .transform(|x| *x).collect(); ast::item_impl(/*bad*/ copy *a, b, c, methods) } ast::item_trait(ref a, ref b, ref methods) => { - let methods = methods.filtered(|m| trait_method_in_cfg(cx, m) ); + let methods = methods.iter().filter(|m| trait_method_in_cfg(cx, *m) ) + .transform(|x| /* bad */copy *x).collect(); ast::item_trait(/*bad*/copy *a, /*bad*/copy *b, methods) } ref item => /*bad*/ copy *item @@ -134,19 +137,12 @@ fn fold_block( b: &ast::blk_, fld: @fold::ast_fold ) -> ast::blk_ { - let filtered_stmts = - b.stmts.filter_mapped(|a| filter_stmt(cx, *a)); - let filtered_view_items = - b.view_items.filter_mapped(|a| filter_view_item(cx, *a)); - let filtered_view_items = - filtered_view_items.map(|x| fld.fold_view_item(*x)); - let mut resulting_stmts = ~[]; - for filtered_stmts.iter().advance |stmt| { - match fld.fold_stmt(*stmt) { - None => {} - Some(stmt) => resulting_stmts.push(stmt), - } - } + let resulting_stmts = do b.stmts.iter().filter_map |a| { + filter_stmt(cx, *a).chain(|stmt| fld.fold_stmt(stmt)) + }.collect(); + let filtered_view_items = do b.view_items.iter().filter_map |a| { + filter_view_item(cx, *a).map(|x| fld.fold_view_item(*x)) + }.collect(); ast::blk_ { view_items: filtered_view_items, stmts: resulting_stmts, @@ -193,7 +189,9 @@ pub fn metas_in_cfg(cfg: &[@ast::meta_item], // Pull the inner meta_items from the #[cfg(meta_item, ...)] attributes, // so we can match against them. This is the list of configurations for // which the item is valid - let cfg_metas = vec::filter_map(cfg_metas, |i| attr::get_meta_item_list(i)); + let cfg_metas = cfg_metas.consume_iter() + .filter_map(|i| attr::get_meta_item_list(i)) + .collect::<~[~[@ast::meta_item]]>(); if cfg_metas.iter().all(|c| c.is_empty()) { return true; } diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs index 41c70c4c5b41..91000d68aad0 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -109,9 +109,11 @@ fn fold_mod(cx: @mut TestCtxt, fn nomain(cx: @mut TestCtxt, item: @ast::item) -> @ast::item { if !*cx.sess.building_library { - @ast::item{attrs: item.attrs.filtered(|attr| { - "main" != attr::get_attr_name(attr) - }),.. copy *item} + @ast::item{ + attrs: do item.attrs.iter().filter_map |attr| { + if "main" != attr::get_attr_name(attr) {Some(*attr)} else {None} + }.collect(), + .. copy *item} } else { item } } @@ -229,10 +231,10 @@ fn is_ignored(cx: @mut TestCtxt, i: @ast::item) -> bool { let ignoreattrs = attr::find_attrs_by_name(i.attrs, "ignore"); let ignoreitems = attr::attr_metas(ignoreattrs); return if !ignoreitems.is_empty() { - let cfg_metas = - vec::concat( - vec::filter_map(ignoreitems, - |i| attr::get_meta_item_list(i))); + let cfg_metas = ignoreitems.consume_iter() + .filter_map(|i| attr::get_meta_item_list(i)) + .collect::<~[~[@ast::meta_item]]>() + .concat_vec(); config::metas_in_cfg(/*bad*/copy cx.crate.node.config, cfg_metas) } else { false diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index c6d7314f1cd9..72b6f8e1c805 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -291,16 +291,16 @@ fn encode_ast(ebml_w: &mut writer::Encoder, item: ast::inlined_item) { // inlined items. fn simplify_ast(ii: &ast::inlined_item) -> ast::inlined_item { fn drop_nested_items(blk: &ast::blk_, fld: @fold::ast_fold) -> ast::blk_ { - let stmts_sans_items = do blk.stmts.filtered |stmt| { + let stmts_sans_items = do blk.stmts.iter().filter_map |stmt| { match stmt.node { ast::stmt_expr(_, _) | ast::stmt_semi(_, _) | - ast::stmt_decl(@codemap::spanned { node: ast::decl_local(_), - span: _}, _) => true, - ast::stmt_decl(@codemap::spanned { node: ast::decl_item(_), - span: _}, _) => false, + ast::stmt_decl(@codemap::spanned { node: ast::decl_local(_), span: _}, _) + => Some(*stmt), + ast::stmt_decl(@codemap::spanned { node: ast::decl_item(_), span: _}, _) + => None, ast::stmt_mac(*) => fail!("unexpanded macro in astencode") } - }; + }.collect(); let blk_sans_items = ast::blk_ { view_items: ~[], // I don't know if we need the view_items here, // but it doesn't break tests! diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 72896258b2d3..740499bbf25e 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -95,7 +95,7 @@ pub fn check_expr(cx: @MatchCheckCtxt, ex: @expr, (s, v): ((), visit::vt<()>)) { } _ => { /* We assume only enum types can be uninhabited */ } } - let arms = vec::concat(arms.filter_mapped(unguarded_pat)); + let arms = arms.iter().filter_map(unguarded_pat).collect::<~[~[@pat]]>().concat_vec(); if arms.is_empty() { cx.tcx.sess.span_err(ex.span, "non-exhaustive patterns"); } else { @@ -265,7 +265,7 @@ pub fn is_useful(cx: &MatchCheckCtxt, m: &matrix, v: &[@pat]) -> useful { } Some(ref ctor) => { match is_useful(cx, - &m.filter_mapped(|r| default(cx, *r)), + &m.iter().filter_map(|r| default(cx, *r)).collect::(), v.tail()) { useful_ => useful(left_ty, /*bad*/copy *ctor), ref u => (/*bad*/copy *u) @@ -287,7 +287,7 @@ pub fn is_useful_specialized(cx: &MatchCheckCtxt, arity: uint, lty: ty::t) -> useful { - let ms = m.filter_mapped(|r| specialize(cx, *r, &ctor, arity, lty)); + let ms = m.iter().filter_map(|r| specialize(cx, *r, &ctor, arity, lty)).collect::(); let could_be_useful = is_useful( cx, &ms, specialize(cx, v, &ctor, arity, lty).get()); match could_be_useful { @@ -397,14 +397,14 @@ pub fn missing_ctor(cx: &MatchCheckCtxt, ty::ty_unboxed_vec(*) | ty::ty_evec(*) => { // Find the lengths and slices of all vector patterns. - let vec_pat_lens = do m.filter_mapped |r| { + let vec_pat_lens = do m.iter().filter_map |r| { match r[0].node { pat_vec(ref before, ref slice, ref after) => { Some((before.len() + after.len(), slice.is_some())) } _ => None } - }; + }.collect::<~[(uint, bool)]>(); // Sort them by length such that for patterns of the same length, // those with a destructured slice come first. diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs index dc88ecbe936b..75b1830778b1 100644 --- a/src/librustc/middle/trans/controlflow.rs +++ b/src/librustc/middle/trans/controlflow.rs @@ -26,7 +26,6 @@ use util::ppaux; use middle::trans::type_::Type; use std::str; -use std::vec; use syntax::ast; use syntax::ast::ident; use syntax::ast_map::path_mod; @@ -190,9 +189,13 @@ pub fn trans_log(log_ex: &ast::expr, let (modpath, modname) = { let path = &mut bcx.fcx.path; - let modpath = vec::append( - ~[path_mod(ccx.sess.ident_of(ccx.link_meta.name))], - path.filtered(|e| match *e { path_mod(_) => true, _ => false })); + let mut modpath = ~[path_mod(ccx.sess.ident_of(ccx.link_meta.name))]; + for path.iter().advance |e| { + match *e { + path_mod(_) => { modpath.push(*e) } + _ => {} + } + } let modname = path_str(ccx.sess, modpath); (modpath, modname) }; diff --git a/src/librustdoc/attr_parser.rs b/src/librustdoc/attr_parser.rs index 7655e173e4e2..0681cf867f13 100644 --- a/src/librustdoc/attr_parser.rs +++ b/src/librustdoc/attr_parser.rs @@ -45,9 +45,9 @@ pub fn parse_crate(attrs: ~[ast::attribute]) -> CrateAttrs { } pub fn parse_desc(attrs: ~[ast::attribute]) -> Option<~str> { - let doc_strs = do doc_metas(attrs).filter_mapped |meta| { - attr::get_meta_item_value_str(*meta).map(|s| s.to_owned()) - }; + let doc_strs = do doc_metas(attrs).consume_iter().filter_map |meta| { + attr::get_meta_item_value_str(meta).map(|s| s.to_owned()) + }.collect::<~[~str]>(); if doc_strs.is_empty() { None } else { diff --git a/src/librustdoc/doc.rs b/src/librustdoc/doc.rs index b45550c06e44..ffb4642be810 100644 --- a/src/librustdoc/doc.rs +++ b/src/librustdoc/doc.rs @@ -13,8 +13,6 @@ use doc; -use std::vec; - pub type AstId = int; #[deriving(Eq)] @@ -186,87 +184,64 @@ impl Doc { } } +macro_rules! filt_mapper { + ($vec:expr, $pat:pat) => { + do ($vec).iter().filter_map |thing| { + match thing { + &$pat => Some(copy *x), + _ => None + } + }.collect() + } +} + +macro_rules! md { + ($id:ident) => { + filt_mapper!(self.items, $id(ref x)) + } +} /// Some helper methods on ModDoc, mostly for testing impl ModDoc { pub fn mods(&self) -> ~[ModDoc] { - do vec::filter_mapped(self.items) |itemtag| { - match copy *itemtag { - ModTag(ModDoc) => Some(ModDoc), - _ => None - } - } + md!(ModTag) } pub fn nmods(&self) -> ~[NmodDoc] { - do vec::filter_mapped(self.items) |itemtag| { - match copy *itemtag { - NmodTag(nModDoc) => Some(nModDoc), - _ => None - } - } + md!(NmodTag) } pub fn fns(&self) -> ~[FnDoc] { - do vec::filter_mapped(self.items) |itemtag| { - match copy *itemtag { - FnTag(FnDoc) => Some(FnDoc), - _ => None - } - } + md!(FnTag) } pub fn consts(&self) -> ~[ConstDoc] { - do vec::filter_mapped(self.items) |itemtag| { - match copy *itemtag { - ConstTag(ConstDoc) => Some(ConstDoc), - _ => None - } - } + md!(ConstTag) } pub fn enums(&self) -> ~[EnumDoc] { - do vec::filter_mapped(self.items) |itemtag| { - match copy *itemtag { - EnumTag(EnumDoc) => Some(EnumDoc), - _ => None - } - } + md!(EnumTag) } pub fn traits(&self) -> ~[TraitDoc] { - do vec::filter_mapped(self.items) |itemtag| { - match copy *itemtag { - TraitTag(TraitDoc) => Some(TraitDoc), - _ => None - } - } + md!(TraitTag) } pub fn impls(&self) -> ~[ImplDoc] { - do vec::filter_mapped(self.items) |itemtag| { - match copy *itemtag { - ImplTag(ImplDoc) => Some(ImplDoc), - _ => None - } - } + md!(ImplTag) } pub fn types(&self) -> ~[TyDoc] { - do vec::filter_mapped(self.items) |itemtag| { - match copy *itemtag { - TyTag(TyDoc) => Some(TyDoc), - _ => None - } - } + md!(TyTag) } pub fn structs(&self) -> ~[StructDoc] { - do vec::filter_mapped(self.items) |itemtag| { - match copy *itemtag { - StructTag(StructDoc) => Some(StructDoc), - _ => None - } - } + md!(StructTag) + } +} + +macro_rules! pu { + ($id:ident) => { + filt_mapper!(*self, ItemPage($id(ref x))) } } @@ -284,75 +259,35 @@ pub trait PageUtils { impl PageUtils for ~[Page] { fn mods(&self) -> ~[ModDoc] { - do vec::filter_mapped(*self) |page| { - match copy *page { - ItemPage(ModTag(ModDoc)) => Some(ModDoc), - _ => None - } - } + pu!(ModTag) } fn nmods(&self) -> ~[NmodDoc] { - do vec::filter_mapped(*self) |page| { - match copy *page { - ItemPage(NmodTag(nModDoc)) => Some(nModDoc), - _ => None - } - } + pu!(NmodTag) } fn fns(&self) -> ~[FnDoc] { - do vec::filter_mapped(*self) |page| { - match copy *page { - ItemPage(FnTag(FnDoc)) => Some(FnDoc), - _ => None - } - } + pu!(FnTag) } fn consts(&self) -> ~[ConstDoc] { - do vec::filter_mapped(*self) |page| { - match copy *page { - ItemPage(ConstTag(ConstDoc)) => Some(ConstDoc), - _ => None - } - } + pu!(ConstTag) } fn enums(&self) -> ~[EnumDoc] { - do vec::filter_mapped(*self) |page| { - match copy *page { - ItemPage(EnumTag(EnumDoc)) => Some(EnumDoc), - _ => None - } - } + pu!(EnumTag) } fn traits(&self) -> ~[TraitDoc] { - do vec::filter_mapped(*self) |page| { - match copy *page { - ItemPage(TraitTag(TraitDoc)) => Some(TraitDoc), - _ => None - } - } + pu!(TraitTag) } fn impls(&self) -> ~[ImplDoc] { - do vec::filter_mapped(*self) |page| { - match copy *page { - ItemPage(ImplTag(ImplDoc)) => Some(ImplDoc), - _ => None - } - } + pu!(ImplTag) } fn types(&self) -> ~[TyDoc] { - do vec::filter_mapped(*self) |page| { - match copy *page { - ItemPage(TyTag(TyDoc)) => Some(TyDoc), - _ => None - } - } + pu!(TyTag) } } diff --git a/src/librustdoc/extract.rs b/src/librustdoc/extract.rs index d5d2b4ce6286..01b77a985fed 100644 --- a/src/librustdoc/extract.rs +++ b/src/librustdoc/extract.rs @@ -15,7 +15,6 @@ use astsrv; use doc::ItemUtils; use doc; -use std::vec; use syntax::ast; use syntax::parse::token::{ident_interner, ident_to_str}; use syntax::parse::token; @@ -83,7 +82,7 @@ fn moddoc_from_mod( ) -> doc::ModDoc { doc::ModDoc { item: itemdoc, - items: do vec::filter_mapped(module_.items) |item| { + items: do module_.items.iter().filter_map |item| { let ItemDoc = mk_itemdoc(item.id, to_str(item.ident)); match copy item.node { ast::item_mod(m) => { @@ -133,7 +132,7 @@ fn moddoc_from_mod( } _ => None } - }, + }.collect(), index: None } } diff --git a/src/librustdoc/page_pass.rs b/src/librustdoc/page_pass.rs index 508cf302ede5..83a0d44978ec 100644 --- a/src/librustdoc/page_pass.rs +++ b/src/librustdoc/page_pass.rs @@ -128,13 +128,12 @@ fn fold_mod( fn strip_mod(doc: doc::ModDoc) -> doc::ModDoc { doc::ModDoc { - items: do doc.items.filtered |item| { - match *item { - doc::ModTag(_) => false, - doc::NmodTag(_) => false, + items: do doc.items.iter().filter |item| { + match **item { + doc::ModTag(_) | doc::NmodTag(_) => false, _ => true } - }, + }.transform(|x| copy *x).collect::<~[doc::ItemTag]>(), .. copy doc } } diff --git a/src/librustdoc/prune_hidden_pass.rs b/src/librustdoc/prune_hidden_pass.rs index 484eb8c7980d..96c5df10680c 100644 --- a/src/librustdoc/prune_hidden_pass.rs +++ b/src/librustdoc/prune_hidden_pass.rs @@ -41,9 +41,9 @@ fn fold_mod( let doc = fold::default_any_fold_mod(fold, doc); doc::ModDoc { - items: do doc.items.filtered |ItemTag| { - !is_hidden(fold.ctxt.clone(), ItemTag.item()) - }, + items: do doc.items.iter().filter |item_tag| { + !is_hidden(fold.ctxt.clone(), item_tag.item()) + }.transform(|x| copy *x).collect(), .. doc } } diff --git a/src/librustdoc/prune_private_pass.rs b/src/librustdoc/prune_private_pass.rs index cb7da801e96e..aeb6e02f244f 100644 --- a/src/librustdoc/prune_private_pass.rs +++ b/src/librustdoc/prune_private_pass.rs @@ -80,7 +80,7 @@ fn strip_priv_methods( methods: &[@ast::method], item_vis: ast::visibility ) -> doc::ImplDoc { - let methods = do (&doc.methods).filtered |method| { + let methods = do doc.methods.iter().filter |method| { let ast_method = do methods.iter().find_ |m| { extract::to_str(m.ident) == method.name }; @@ -91,7 +91,7 @@ fn strip_priv_methods( ast::private => false, ast::inherited => item_vis == ast::public } - }; + }.transform(|x| copy *x).collect(); doc::ImplDoc { methods: methods, @@ -106,9 +106,9 @@ fn fold_mod( let doc = fold::default_any_fold_mod(fold, doc); doc::ModDoc { - items: doc.items.filtered(|ItemTag| { - match ItemTag { - &doc::ImplTag(ref doc) => { + items: doc.items.iter().filter(|item_tag| { + match item_tag { + & &doc::ImplTag(ref doc) => { if doc.trait_types.is_empty() { // This is an associated impl. We have already pruned the // non-visible methods. If there are any left then @@ -123,10 +123,10 @@ fn fold_mod( } } _ => { - is_visible(fold.ctxt.clone(), ItemTag.item()) + is_visible(fold.ctxt.clone(), item_tag.item()) } } - }), + }).transform(|x| copy *x).collect(), .. doc } } diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index 669e5042d3bf..1e99a3fa4bcd 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -77,9 +77,9 @@ fn fold_mod(_ctx: @mut ReadyCtx, fold: @fold::ast_fold) -> ast::_mod { fn strip_main(item: @ast::item) -> @ast::item { @ast::item { - attrs: do item.attrs.filtered |attr| { - "main" != attr::get_attr_name(attr) - }, + attrs: do item.attrs.iter().filter_map |attr| { + if "main" != attr::get_attr_name(attr) {Some(*attr)} else {None} + }.collect(), .. copy *item } } diff --git a/src/librustpkg/workspace.rs b/src/librustpkg/workspace.rs index dd2cf445302a..5876dbdc9dea 100644 --- a/src/librustpkg/workspace.rs +++ b/src/librustpkg/workspace.rs @@ -34,6 +34,7 @@ pub fn each_pkg_parent_workspace(pkgid: &PkgId, action: &fn(&Path) -> bool) -> b } pub fn pkg_parent_workspaces(pkgid: &PkgId) -> ~[Path] { - rust_path().filtered(|ws| - workspace_contains_package_id(pkgid, ws)) + rust_path().consume_iter() + .filter(|ws| workspace_contains_package_id(pkgid, ws)) + .collect() } diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 39041b483697..c994bbf6fa49 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -777,9 +777,9 @@ pub fn list_dir(p: &Path) -> ~[~str] { strings } } - do get_list(p).filtered |filename| { - *filename != ~"." && *filename != ~".." - } + do get_list(p).consume_iter().filter |filename| { + "." != *filename && ".." != *filename + }.collect() } } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 3fa9df2a9e0d..5d4943c49d9c 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -309,77 +309,6 @@ pub fn flat_map(v: &[T], f: &fn(t: &T) -> ~[U]) -> ~[U] { result } -pub fn filter_map( - v: ~[T], - f: &fn(t: T) -> Option) -> ~[U] -{ - /*! - * - * Apply a function to each element of a vector and return the results. - * Consumes the input vector. If function `f` returns `None` then that - * element is excluded from the resulting vector. - */ - - let mut result = ~[]; - for v.consume_iter().advance |elem| { - match f(elem) { - None => {} - Some(result_elem) => { result.push(result_elem); } - } - } - result -} - -pub fn filter_mapped( - v: &[T], - f: &fn(t: &T) -> Option) -> ~[U] -{ - /*! - * - * Like `filter_map()`, but operates on a borrowed slice - * and does not consume the input. - */ - - let mut result = ~[]; - for v.iter().advance |elem| { - match f(elem) { - None => {/* no-op */ } - Some(result_elem) => { result.push(result_elem); } - } - } - result -} - -/** - * Construct a new vector from the elements of a vector for which some - * predicate holds. - * - * Apply function `f` to each element of `v` and return a vector containing - * only those elements for which `f` returned true. - */ -pub fn filter(v: ~[T], f: &fn(t: &T) -> bool) -> ~[T] { - let mut result = ~[]; - for v.consume_iter().advance |elem| { - if f(&elem) { result.push(elem); } - } - result -} - -/** - * Construct a new vector from the elements of a vector for which some - * predicate holds. - * - * Apply function `f` to each element of `v` and return a vector containing - * only those elements for which `f` returned true. - */ -pub fn filtered(v: &[T], f: &fn(t: &T) -> bool) -> ~[T] { - let mut result = ~[]; - for v.iter().advance |elem| { - if f(elem) { result.push(copy *elem); } - } - result -} - /// Flattens a vector of vectors of T into a single vector of T. pub fn concat(v: &[~[T]]) -> ~[T] { v.concat_vec() } @@ -866,7 +795,6 @@ pub trait ImmutableVector<'self, T> { fn last_opt(&self) -> Option<&'self T>; fn rposition(&self, f: &fn(t: &T) -> bool) -> Option; fn flat_map(&self, f: &fn(t: &T) -> ~[U]) -> ~[U]; - fn filter_mapped(&self, f: &fn(t: &T) -> Option) -> ~[U]; unsafe fn unsafe_ref(&self, index: uint) -> *T; fn bsearch(&self, f: &fn(&T) -> Ordering) -> Option; @@ -976,17 +904,6 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { fn flat_map(&self, f: &fn(t: &T) -> ~[U]) -> ~[U] { flat_map(*self, f) } - /** - * Apply a function to each element of a vector and return the results - * - * If function `f` returns `none` then that element is excluded from - * the resulting vector. - */ - #[inline] - fn filter_mapped(&self, f: &fn(t: &T) -> Option) -> ~[U] { - filter_mapped(*self, f) - } - /// Returns a pointer to the element at the given index, without doing /// bounds checking. #[inline] @@ -1077,25 +994,12 @@ impl<'self, T: TotalOrd> ImmutableTotalOrdVector for &'self [T] { #[allow(missing_doc)] pub trait ImmutableCopyableVector { - fn filtered(&self, f: &fn(&T) -> bool) -> ~[T]; fn partitioned(&self, f: &fn(&T) -> bool) -> (~[T], ~[T]); unsafe fn unsafe_get(&self, elem: uint) -> T; } /// Extension methods for vectors impl<'self,T:Copy> ImmutableCopyableVector for &'self [T] { - /** - * Construct a new vector from the elements of a vector for which some - * predicate holds. - * - * Apply function `f` to each element of `v` and return a vector - * containing only those elements for which `f` returned true. - */ - #[inline] - fn filtered(&self, f: &fn(t: &T) -> bool) -> ~[T] { - filtered(*self, f) - } - /** * Partitions the vector into those that satisfies the predicate, and * those that do not. @@ -1144,7 +1048,6 @@ pub trait OwnedVector { fn swap_remove(&mut self, index: uint) -> T; fn truncate(&mut self, newlen: uint); fn retain(&mut self, f: &fn(t: &T) -> bool); - fn filter(self, f: &fn(t: &T) -> bool) -> ~[T]; fn partition(self, f: &fn(&T) -> bool) -> (~[T], ~[T]); fn grow_fn(&mut self, n: uint, op: &fn(uint) -> T); } @@ -1482,11 +1385,6 @@ impl OwnedVector for ~[T] { } } - #[inline] - fn filter(self, f: &fn(&T) -> bool) -> ~[T] { - filter(self, f) - } - /** * Partitions the vector into those that satisfies the predicate, and * those that do not. @@ -2616,87 +2514,6 @@ mod tests { assert_eq!(w[4], 25u); } - #[test] - fn test_filter_mapped() { - // Test on-stack filter-map. - let mut v = ~[1u, 2u, 3u]; - let mut w = filter_mapped(v, square_if_odd_r); - assert_eq!(w.len(), 2u); - assert_eq!(w[0], 1u); - assert_eq!(w[1], 9u); - - // Test on-heap filter-map. - v = ~[1u, 2u, 3u, 4u, 5u]; - w = filter_mapped(v, square_if_odd_r); - assert_eq!(w.len(), 3u); - assert_eq!(w[0], 1u); - assert_eq!(w[1], 9u); - assert_eq!(w[2], 25u); - - fn halve(i: &int) -> Option { - if *i % 2 == 0 { - Some::(*i / 2) - } else { - None:: - } - } - fn halve_for_sure(i: &int) -> int { *i / 2 } - let all_even: ~[int] = ~[0, 2, 8, 6]; - let all_odd1: ~[int] = ~[1, 7, 3]; - let all_odd2: ~[int] = ~[]; - let mix: ~[int] = ~[9, 2, 6, 7, 1, 0, 0, 3]; - let mix_dest: ~[int] = ~[1, 3, 0, 0]; - assert!(filter_mapped(all_even, halve) == - all_even.map(halve_for_sure)); - assert_eq!(filter_mapped(all_odd1, halve), ~[]); - assert_eq!(filter_mapped(all_odd2, halve), ~[]); - assert_eq!(filter_mapped(mix, halve), mix_dest); - } - - #[test] - fn test_filter_map() { - // Test on-stack filter-map. - let mut v = ~[1u, 2u, 3u]; - let mut w = filter_map(v, square_if_odd_v); - assert_eq!(w.len(), 2u); - assert_eq!(w[0], 1u); - assert_eq!(w[1], 9u); - - // Test on-heap filter-map. - v = ~[1u, 2u, 3u, 4u, 5u]; - w = filter_map(v, square_if_odd_v); - assert_eq!(w.len(), 3u); - assert_eq!(w[0], 1u); - assert_eq!(w[1], 9u); - assert_eq!(w[2], 25u); - - fn halve(i: int) -> Option { - if i % 2 == 0 { - Some::(i / 2) - } else { - None:: - } - } - fn halve_for_sure(i: &int) -> int { *i / 2 } - let all_even: ~[int] = ~[0, 2, 8, 6]; - let all_even0: ~[int] = copy all_even; - let all_odd1: ~[int] = ~[1, 7, 3]; - let all_odd2: ~[int] = ~[]; - let mix: ~[int] = ~[9, 2, 6, 7, 1, 0, 0, 3]; - let mix_dest: ~[int] = ~[1, 3, 0, 0]; - assert!(filter_map(all_even, halve) == - all_even0.map(halve_for_sure)); - assert_eq!(filter_map(all_odd1, halve), ~[]); - assert_eq!(filter_map(all_odd2, halve), ~[]); - assert_eq!(filter_map(mix, halve), mix_dest); - } - - #[test] - fn test_filter() { - assert_eq!(filter(~[1u, 2u, 3u], is_odd), ~[1u, 3u]); - assert_eq!(filter(~[1u, 2u, 4u, 8u, 16u], is_three), ~[]); - } - #[test] fn test_retain() { let mut v = ~[1, 2, 3, 4, 5]; @@ -3227,38 +3044,6 @@ mod tests { }; } - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_filter_mapped_fail() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do filter_mapped(v) |_elt| { - if i == 2 { - fail!() - } - i += 0; - Some((~0, @0)) - }; - } - - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_filter_fail() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do v.filtered |_elt| { - if i == 2 { - fail!() - } - i += 0; - true - }; - } - #[test] #[ignore(windows)] #[should_fail] diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 529d5bfe70b4..ce8e24fd4445 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -238,12 +238,12 @@ pub fn unguarded_pat(a: &arm) -> Option<~[@pat]> { } pub fn public_methods(ms: ~[@method]) -> ~[@method] { - do ms.filtered |m| { + do ms.consume_iter().filter |m| { match m.vis { public => true, _ => false } - } + }.collect() } // extract a ty_method from a trait_method. if the trait_method is diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index a1a0c7006288..d04d96b2481d 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -143,13 +143,13 @@ pub fn get_name_value_str_pair(item: @ast::meta_item) /// Search a list of attributes and return only those with a specific name pub fn find_attrs_by_name(attrs: &[ast::attribute], name: &str) -> ~[ast::attribute] { - do vec::filter_mapped(attrs) |a| { + do attrs.iter().filter_map |a| { if name == get_attr_name(a) { Some(*a) } else { None } - } + }.collect() } /// Search a list of meta items and return only those with a specific name @@ -277,14 +277,7 @@ pub fn sort_meta_items(items: &[@ast::meta_item]) -> ~[@ast::meta_item] { pub fn remove_meta_items_by_name(items: ~[@ast::meta_item], name: &str) -> ~[@ast::meta_item] { - - return vec::filter_mapped(items, |item| { - if name != get_meta_item_name(*item) { - Some(*item) - } else { - None - } - }); + items.consume_iter().filter(|item| name != get_meta_item_name(*item)).collect() } /** diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 4e1451239962..96d7685353b2 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -14,8 +14,6 @@ use codemap::{span, spanned}; use parse::token; use opt_vec::OptVec; -use std::vec; - pub trait ast_fold { fn fold_crate(@self, &crate) -> crate; fn fold_view_item(@self, @view_item) -> @view_item; @@ -700,7 +698,7 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ { pub fn noop_fold_mod(m: &_mod, fld: @ast_fold) -> _mod { ast::_mod { view_items: m.view_items.iter().transform(|x| fld.fold_view_item(*x)).collect(), - items: vec::filter_mapped(m.items, |x| fld.fold_item(*x)), + items: m.items.iter().filter_map(|x| fld.fold_item(*x)).collect(), } } diff --git a/src/test/compile-fail/lint-unused-imports.rs b/src/test/compile-fail/lint-unused-imports.rs index e61de0ac11f4..e7e01a404872 100644 --- a/src/test/compile-fail/lint-unused-imports.rs +++ b/src/test/compile-fail/lint-unused-imports.rs @@ -30,7 +30,7 @@ use std::io::WriterUtil; // Make sure this import is warned about when at least one of its imported names // is unused -use std::vec::{filter, from_elem}; //~ ERROR unused import +use std::vec::{from_fn, from_elem}; //~ ERROR unused import mod foo { pub struct Point{x: int, y: int} From 920780258999aa4a2669a594464cda780798d35f Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Tue, 2 Jul 2013 12:58:23 +1000 Subject: [PATCH 26/93] Remove vec::reversed, replaced by iterators. --- src/libextra/num/bigint.rs | 19 +++++++++-------- src/librustc/middle/resolve.rs | 3 +-- src/libstd/vec.rs | 28 ++------------------------ src/test/run-pass/import-glob-crate.rs | 2 +- 4 files changed, 15 insertions(+), 37 deletions(-) diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs index 25aeccdcbed0..338fd86ad1ee 100644 --- a/src/libextra/num/bigint.rs +++ b/src/libextra/num/bigint.rs @@ -520,10 +520,12 @@ impl ToStrRadix for BigUint { fn fill_concat(v: &[BigDigit], radix: uint, l: uint) -> ~str { if v.is_empty() { return ~"0" } - let s = vec::reversed(v).map(|n| { - let s = uint::to_str_radix(*n as uint, radix); - str::from_chars(vec::from_elem(l - s.len(), '0')) + s - }).concat(); + let mut s = str::with_capacity(v.len() * l); + for v.rev_iter().advance |n| { + let ss = uint::to_str_radix(*n as uint, radix); + s.push_str("0".repeat(l - ss.len())); + s.push_str(ss); + } s.trim_left_chars(&'0').to_owned() } } @@ -1629,7 +1631,6 @@ mod bigint_tests { use std::int; use std::num::{IntConvertible, Zero, One, FromStrRadix}; use std::uint; - use std::vec; #[test] fn test_from_biguint() { @@ -1646,9 +1647,11 @@ mod bigint_tests { #[test] fn test_cmp() { - let vs = [ &[2], &[1, 1], &[2, 1], &[1, 1, 1] ]; - let mut nums = vec::reversed(vs) - .map(|s| BigInt::from_slice(Minus, *s)); + let vs = [ &[2 as BigDigit], &[1, 1], &[2, 1], &[1, 1, 1] ]; + let mut nums = ~[]; + for vs.rev_iter().advance |s| { + nums.push(BigInt::from_slice(Minus, *s)); + } nums.push(Zero::zero()); nums.push_all_move(vs.map(|s| BigInt::from_slice(Plus, *s))); diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 6847e298a2cb..ebd11e2f6685 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -41,7 +41,6 @@ use syntax::opt_vec::OptVec; use std::str; use std::uint; -use std::vec; use std::hashmap::{HashMap, HashSet}; use std::util; @@ -5360,7 +5359,7 @@ impl Resolver { if idents.len() == 0 { return ~"???"; } - return self.idents_to_str(vec::reversed(idents)); + return self.idents_to_str(idents.consume_rev_iter().collect::<~[ast::ident]>()); } pub fn dump_module(@mut self, module_: @mut Module) { diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 5d4943c49d9c..b6d99d920e21 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -436,16 +436,6 @@ pub fn zip(mut v: ~[T], mut u: ~[U]) -> ~[(T, U)] { w } -/// Returns a vector with the order of elements reversed -pub fn reversed(v: &[T]) -> ~[T] { - let mut rs: ~[T] = ~[]; - let mut i = v.len(); - if i == 0 { return (rs); } else { i -= 1; } - while i != 0 { rs.push(copy v[i]); i -= 1; } - rs.push(copy v[0]); - rs -} - /** * Iterate over all permutations of vector `v`. * @@ -2628,31 +2618,17 @@ mod tests { } #[test] - fn reverse_and_reversed() { + fn test_reverse() { let mut v: ~[int] = ~[10, 20]; assert_eq!(v[0], 10); assert_eq!(v[1], 20); v.reverse(); assert_eq!(v[0], 20); assert_eq!(v[1], 10); - let v2 = reversed::([10, 20]); - assert_eq!(v2[0], 20); - assert_eq!(v2[1], 10); - v[0] = 30; - assert_eq!(v2[0], 20); - // Make sure they work with 0-length vectors too. - let v4 = reversed::([]); - assert_eq!(v4, ~[]); let mut v3: ~[int] = ~[]; v3.reverse(); - } - - #[test] - fn reversed_mut() { - let v2 = reversed::([10, 20]); - assert_eq!(v2[0], 20); - assert_eq!(v2[1], 10); + assert!(v3.is_empty()); } #[test] diff --git a/src/test/run-pass/import-glob-crate.rs b/src/test/run-pass/import-glob-crate.rs index b036a57e19cb..d09ef3bc25c3 100644 --- a/src/test/run-pass/import-glob-crate.rs +++ b/src/test/run-pass/import-glob-crate.rs @@ -17,5 +17,5 @@ use std::vec::*; pub fn main() { let mut v = from_elem(0u, 0); v = append(v, ~[4, 2]); - assert_eq!(reversed(v), ~[2, 4]); + assert_eq!(from_fn(2, |i| 2*(i+1)), ~[2, 4]); } From f19fb2459f4fc695225f996692a6a6b30b801ee9 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Wed, 3 Jul 2013 12:13:00 +1000 Subject: [PATCH 27/93] Remove standalone comparison functions in vec, make the trait impls better. --- src/compiletest/runtest.rs | 5 +- src/libextra/crypto/sha1.rs | 5 +- src/libextra/flatpipes.rs | 7 +- src/libextra/num/bigint.rs | 18 +- src/librustc/middle/trans/adt.rs | 10 +- src/librustc/middle/trans/foreign.rs | 2 +- src/librustc/middle/trans/reflect.rs | 2 +- src/librustc/middle/trans/type_.rs | 2 +- src/librustdoc/desc_to_brief_pass.rs | 9 +- src/librustdoc/markdown_pass.rs | 2 +- src/librustdoc/markdown_writer.rs | 2 +- src/libstd/at_vec.rs | 9 +- src/libstd/prelude.rs | 2 +- src/libstd/vec.rs | 313 +++++++++++------------ src/test/bench/task-perf-alloc-unwind.rs | 2 +- 15 files changed, 184 insertions(+), 206 deletions(-) diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 06422a49b65f..8e493fd5396f 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -601,9 +601,8 @@ fn make_run_args(config: &config, _props: &TestProps, testfile: &Path) -> ProcArgs { // If we've got another tool to run under (valgrind), // then split apart its command - let toolargs = split_maybe_args(&config.runtool); - - let mut args = toolargs + [make_exe_name(config, testfile).to_str()]; + let mut args = split_maybe_args(&config.runtool); + args.push(make_exe_name(config, testfile).to_str()); let prog = args.shift(); return ProcArgs {prog: prog, args: args}; } diff --git a/src/libextra/crypto/sha1.rs b/src/libextra/crypto/sha1.rs index 238e4a4d238d..0f2d44f57e34 100644 --- a/src/libextra/crypto/sha1.rs +++ b/src/libextra/crypto/sha1.rs @@ -240,7 +240,6 @@ impl Digest for Sha1 { #[cfg(test)] mod tests { - use std::vec; use digest::{Digest, DigestUtil}; use sha1::Sha1; @@ -337,7 +336,7 @@ mod tests { for tests.iter().advance |t| { (*sh).input_str(t.input); sh.result(out); - assert!(vec::eq(t.output, out)); + assert!(t.output.as_slice() == out); let out_str = (*sh).result_str(); assert_eq!(out_str.len(), 40); @@ -357,7 +356,7 @@ mod tests { left = left - take; } sh.result(out); - assert!(vec::eq(t.output, out)); + assert!(t.output.as_slice() == out); let out_str = (*sh).result_str(); assert_eq!(out_str.len(), 40); diff --git a/src/libextra/flatpipes.rs b/src/libextra/flatpipes.rs index e8bdc951ca4e..de0a988f94c8 100644 --- a/src/libextra/flatpipes.rs +++ b/src/libextra/flatpipes.rs @@ -55,7 +55,6 @@ use std::io; use std::comm::GenericChan; use std::comm::GenericPort; use std::sys::size_of; -use std::vec; /** A FlatPort, consisting of a `BytePort` that receives byte vectors, @@ -274,7 +273,7 @@ impl,P:BytePort> GenericPort for FlatPort { } }; - if vec::eq(command, CONTINUE) { + if CONTINUE.as_slice() == command { let msg_len = match self.byte_port.try_recv(size_of::()) { Some(bytes) => { io::u64_from_be_bytes(bytes, 0, size_of::()) @@ -931,7 +930,7 @@ mod test { fn test_try_recv_none3(loader: PortLoader

) { static CONTINUE: [u8, ..4] = [0xAA, 0xBB, 0xCC, 0xDD]; // The control word is followed by garbage - let bytes = CONTINUE.to_owned() + [0]; + let bytes = CONTINUE.to_owned() + &[0u8]; let port = loader(bytes); let res: Option = port.try_recv(); assert!(res.is_none()); @@ -955,7 +954,7 @@ mod test { 1, sys::size_of::()) |len_bytes| { len_bytes.to_owned() }; - let bytes = CONTINUE.to_owned() + len_bytes + [0, 0, 0, 0]; + let bytes = CONTINUE.to_owned() + len_bytes + &[0u8, 0, 0, 0]; let port = loader(bytes); diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs index 338fd86ad1ee..a0b95924e09d 100644 --- a/src/libextra/num/bigint.rs +++ b/src/libextra/num/bigint.rs @@ -207,7 +207,7 @@ impl Add for BigUint { let new_len = uint::max(self.data.len(), other.data.len()); let mut carry = 0; - let sum = do vec::from_fn(new_len) |i| { + let mut sum = do vec::from_fn(new_len) |i| { let ai = if i < self.data.len() { self.data[i] } else { 0 }; let bi = if i < other.data.len() { other.data[i] } else { 0 }; let (hi, lo) = BigDigit::from_uint( @@ -216,8 +216,8 @@ impl Add for BigUint { carry = hi; lo }; - if carry == 0 { return BigUint::new(sum) }; - return BigUint::new(sum + [carry]); + if carry != 0 { sum.push(carry); } + return BigUint::new(sum); } } @@ -284,15 +284,15 @@ impl Mul for BigUint { if n == 1 { return copy *a; } let mut carry = 0; - let prod = do a.data.iter().transform |ai| { + let mut prod = do a.data.iter().transform |ai| { let (hi, lo) = BigDigit::from_uint( (*ai as uint) * (n as uint) + (carry as uint) ); carry = hi; lo }.collect::<~[BigDigit]>(); - if carry == 0 { return BigUint::new(prod) }; - return BigUint::new(prod + [carry]); + if carry != 0 { prod.push(carry); } + return BigUint::new(prod); } @@ -621,15 +621,15 @@ impl BigUint { if n_bits == 0 || self.is_zero() { return copy *self; } let mut carry = 0; - let shifted = do self.data.iter().transform |elem| { + let mut shifted = do self.data.iter().transform |elem| { let (hi, lo) = BigDigit::from_uint( (*elem as uint) << n_bits | (carry as uint) ); carry = hi; lo }.collect::<~[BigDigit]>(); - if carry == 0 { return BigUint::new(shifted); } - return BigUint::new(shifted + [carry]); + if carry != 0 { shifted.push(carry); } + return BigUint::new(shifted); } diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index ab813c0ffc54..4755f7629511 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -131,13 +131,13 @@ fn represent_type_uncached(cx: &mut CrateContext, t: ty::t) -> Repr { } ty::ty_struct(def_id, ref substs) => { let fields = ty::lookup_struct_fields(cx.tcx, def_id); - let ftys = do fields.map |field| { + let mut ftys = do fields.map |field| { ty::lookup_field_type(cx.tcx, def_id, field.id, substs) }; let packed = ty::lookup_packed(cx.tcx, def_id); let dtor = ty::ty_dtor(cx.tcx, def_id).has_drop_flag(); - let ftys = - if dtor { ftys + [ty::mk_bool()] } else { ftys }; + if dtor { ftys.push(ty::mk_bool()); } + return Univariant(mk_struct(cx, ftys, packed), dtor) } ty::ty_enum(def_id, ref substs) => { @@ -263,7 +263,7 @@ fn generic_fields_of(cx: &mut CrateContext, r: &Repr, sizing: bool) -> ~[Type] { let padding = largest_size - most_aligned.size; struct_llfields(cx, most_aligned, sizing) - + [Type::array(&Type::i8(), padding)] + + &[Type::array(&Type::i8(), padding)] } } } @@ -512,7 +512,7 @@ pub fn trans_const(ccx: &mut CrateContext, r: &Repr, discr: int, let discr_ty = C_int(ccx, discr); let contents = build_const_struct(ccx, case, ~[discr_ty] + vals); - C_struct(contents + [padding(max_sz - case.size)]) + C_struct(contents + &[padding(max_sz - case.size)]) } NullablePointer{ nonnull: ref nonnull, nndiscr, ptrfield, _ } => { if discr == nndiscr { diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index c01f01db5fd1..0a3b6d881e47 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -113,7 +113,7 @@ fn shim_types(ccx: @mut CrateContext, id: ast::node_id) -> ShimTypes { _ => ccx.sess.bug("c_arg_and_ret_lltys called on non-function type") }; let llsig = foreign_signature(ccx, &fn_sig); - let bundle_ty = Type::struct_(llsig.llarg_tys + [llsig.llret_ty.ptr_to()], false); + let bundle_ty = Type::struct_(llsig.llarg_tys + &[llsig.llret_ty.ptr_to()], false); let ret_def = !ty::type_is_bot(fn_sig.output) && !ty::type_is_nil(fn_sig.output); let fn_ty = abi_info(ccx).compute_info(llsig.llarg_tys, llsig.llret_ty, ret_def); diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index 9e227da49f83..04133bfe79ac 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -278,7 +278,7 @@ impl Reflector { let opaqueptrty = ty::mk_ptr(ccx.tcx, ty::mt { ty: opaquety, mutbl: ast::m_imm }); let make_get_disr = || { - let sub_path = bcx.fcx.path + [path_name(special_idents::anon)]; + let sub_path = bcx.fcx.path + &[path_name(special_idents::anon)]; let sym = mangle_internal_name_by_path_and_seq(ccx, sub_path, "get_disr"); diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index e52d33fc6e9a..7878e17f7fc6 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -245,7 +245,7 @@ impl Type { } pub fn box(ctx: &CrateContext, ty: &Type) -> Type { - Type::struct_(Type::box_header_fields(ctx) + [*ty], false) + Type::struct_(Type::box_header_fields(ctx) + &[*ty], false) } pub fn opaque_box(ctx: &CrateContext) -> Type { diff --git a/src/librustdoc/desc_to_brief_pass.rs b/src/librustdoc/desc_to_brief_pass.rs index 2077516a9b56..3fd6ad169987 100644 --- a/src/librustdoc/desc_to_brief_pass.rs +++ b/src/librustdoc/desc_to_brief_pass.rs @@ -141,7 +141,7 @@ fn first_sentence_(s: &str) -> ~str { pub fn paragraphs(s: &str) -> ~[~str] { let mut whitespace_lines = 0; let mut accum = ~""; - let paras = do s.any_line_iter().fold(~[]) |paras, line| { + let mut paras = do s.any_line_iter().fold(~[]) |paras, line| { let mut res = paras; if line.is_whitespace() { @@ -166,11 +166,8 @@ pub fn paragraphs(s: &str) -> ~[~str] { res }; - if !accum.is_empty() { - paras + [accum] - } else { - paras - } + if !accum.is_empty() { paras.push(accum); } + paras } #[cfg(test)] diff --git a/src/librustdoc/markdown_pass.rs b/src/librustdoc/markdown_pass.rs index 0705a5c17233..f800a8ab946f 100644 --- a/src/librustdoc/markdown_pass.rs +++ b/src/librustdoc/markdown_pass.rs @@ -172,7 +172,7 @@ pub fn header_kind(doc: doc::ItemTag) -> ~str { } pub fn header_name(doc: doc::ItemTag) -> ~str { - let fullpath = (doc.path() + [doc.name()]).connect("::"); + let fullpath = (doc.path() + &[doc.name()]).connect("::"); match &doc { &doc::ModTag(_) if doc.id() != syntax::ast::crate_node_id => { fullpath diff --git a/src/librustdoc/markdown_writer.rs b/src/librustdoc/markdown_writer.rs index 9621ea0892b9..d757547d8f76 100644 --- a/src/librustdoc/markdown_writer.rs +++ b/src/librustdoc/markdown_writer.rs @@ -163,7 +163,7 @@ pub fn make_filename( } } doc::ItemPage(doc) => { - (doc.path() + [doc.name()]).connect("_") + (doc.path() + &[doc.name()]).connect("_") } } }; diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs index cadd58118edc..37a32d6b0f00 100644 --- a/src/libstd/at_vec.rs +++ b/src/libstd/at_vec.rs @@ -176,13 +176,14 @@ pub fn to_managed(v: &[T]) -> @[T] { #[cfg(not(test))] pub mod traits { use at_vec::append; + use vec::Vector; use kinds::Copy; use ops::Add; - impl<'self,T:Copy> Add<&'self [T],@[T]> for @[T] { + impl<'self,T:Copy, V: Vector> Add for @[T] { #[inline] - fn add(&self, rhs: & &'self [T]) -> @[T] { - append(*self, (*rhs)) + fn add(&self, rhs: &V) -> @[T] { + append(*self, rhs.as_slice()) } } } @@ -312,7 +313,7 @@ mod test { #[test] fn append_test() { - assert_eq!(@[1,2,3] + [4,5,6], @[1,2,3,4,5,6]); + assert_eq!(@[1,2,3] + &[4,5,6], @[1,2,3,4,5,6]); } #[test] diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index 9d5052099609..db534cca971a 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -72,7 +72,7 @@ pub use tuple::{CloneableTuple10, CloneableTuple11, CloneableTuple12}; pub use tuple::{ImmutableTuple2, ImmutableTuple3, ImmutableTuple4, ImmutableTuple5}; pub use tuple::{ImmutableTuple6, ImmutableTuple7, ImmutableTuple8, ImmutableTuple9}; pub use tuple::{ImmutableTuple10, ImmutableTuple11, ImmutableTuple12}; -pub use vec::{VectorVector, CopyableVector, ImmutableVector}; +pub use vec::{Vector, VectorVector, CopyableVector, ImmutableVector}; pub use vec::{ImmutableEqVector, ImmutableTotalOrdVector, ImmutableCopyableVector}; pub use vec::{OwnedVector, OwnedCopyableVector,OwnedEqVector, MutableVector}; pub use io::{Reader, ReaderUtil, Writer, WriterUtil}; diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index b6d99d920e21..b702a1c7281e 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -16,14 +16,13 @@ use cast::transmute; use cast; use container::{Container, Mutable}; use cmp; -use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater}; +use cmp::{Eq, TotalEq, TotalOrd, Ordering, Less, Equal, Greater}; use clone::Clone; use iterator::{FromIterator, Iterator, IteratorUtil}; use kinds::Copy; use libc; use libc::c_void; use num::Zero; -use ops::Add; use option::{None, Option, Some}; use ptr::to_unsafe_ptr; use ptr; @@ -40,8 +39,6 @@ use unstable::intrinsics::{get_tydesc, contains_managed}; use vec; use util; -#[cfg(not(test))] use cmp::Equiv; - #[doc(hidden)] pub mod rustrt { use libc; @@ -549,179 +546,165 @@ pub fn as_mut_buf(s: &mut [T], f: &fn(*mut T, uint) -> U) -> U { // Equality -/// Tests whether two slices are equal to one another. This is only true if both -/// slices are of the same length, and each of the corresponding elements return -/// true when queried via the `eq` function. -fn eq(a: &[T], b: &[T]) -> bool { - let (a_len, b_len) = (a.len(), b.len()); - if a_len != b_len { return false; } +#[cfg(not(test))] +pub mod traits { + use super::Vector; + use kinds::Copy; + use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Equal, Equiv}; + use ops::Add; - let mut i = 0; - while i < a_len { - if a[i] != b[i] { return false; } - i += 1; + impl<'self,T:Eq> Eq for &'self [T] { + fn eq(&self, other: & &'self [T]) -> bool { + self.len() == other.len() && + self.iter().zip(other.iter()).all(|(s,o)| *s == *o) + } + #[inline] + fn ne(&self, other: & &'self [T]) -> bool { !self.eq(other) } } - true -} -/// Similar to the `vec::eq` function, but this is defined for types which -/// implement `TotalEq` as opposed to types which implement `Eq`. Equality -/// comparisons are done via the `equals` function instead of `eq`. -fn equals(a: &[T], b: &[T]) -> bool { - let (a_len, b_len) = (a.len(), b.len()); - if a_len != b_len { return false; } - - let mut i = 0; - while i < a_len { - if !a[i].equals(&b[i]) { return false; } - i += 1; + impl Eq for ~[T] { + #[inline] + fn eq(&self, other: &~[T]) -> bool { self.as_slice() == *other } + #[inline] + fn ne(&self, other: &~[T]) -> bool { !self.eq(other) } } - true -} -#[cfg(not(test))] -impl<'self,T:Eq> Eq for &'self [T] { - #[inline] - fn eq(&self, other: & &'self [T]) -> bool { eq(*self, *other) } - #[inline] - fn ne(&self, other: & &'self [T]) -> bool { !self.eq(other) } -} + impl Eq for @[T] { + #[inline] + fn eq(&self, other: &@[T]) -> bool { self.as_slice() == *other } + #[inline] + fn ne(&self, other: &@[T]) -> bool { !self.eq(other) } + } -#[cfg(not(test))] -impl Eq for ~[T] { - #[inline] - fn eq(&self, other: &~[T]) -> bool { eq(*self, *other) } - #[inline] - fn ne(&self, other: &~[T]) -> bool { !self.eq(other) } -} - -#[cfg(not(test))] -impl Eq for @[T] { - #[inline] - fn eq(&self, other: &@[T]) -> bool { eq(*self, *other) } - #[inline] - fn ne(&self, other: &@[T]) -> bool { !self.eq(other) } -} - -#[cfg(not(test))] -impl<'self,T:TotalEq> TotalEq for &'self [T] { - #[inline] - fn equals(&self, other: & &'self [T]) -> bool { equals(*self, *other) } -} - -#[cfg(not(test))] -impl TotalEq for ~[T] { - #[inline] - fn equals(&self, other: &~[T]) -> bool { equals(*self, *other) } -} - -#[cfg(not(test))] -impl TotalEq for @[T] { - #[inline] - fn equals(&self, other: &@[T]) -> bool { equals(*self, *other) } -} - -#[cfg(not(test))] -impl<'self,T:Eq> Equiv<~[T]> for &'self [T] { - #[inline] - fn equiv(&self, other: &~[T]) -> bool { eq(*self, *other) } -} - -// Lexicographical comparison - -fn cmp(a: &[T], b: &[T]) -> Ordering { - let low = uint::min(a.len(), b.len()); - - for uint::range(0, low) |idx| { - match a[idx].cmp(&b[idx]) { - Greater => return Greater, - Less => return Less, - Equal => () + impl<'self,T:TotalEq> TotalEq for &'self [T] { + fn equals(&self, other: & &'self [T]) -> bool { + self.len() == other.len() && + self.iter().zip(other.iter()).all(|(s,o)| s.equals(o)) } } - a.len().cmp(&b.len()) -} - -#[cfg(not(test))] -impl<'self,T:TotalOrd> TotalOrd for &'self [T] { - #[inline] - fn cmp(&self, other: & &'self [T]) -> Ordering { cmp(*self, *other) } -} - -#[cfg(not(test))] -impl TotalOrd for ~[T] { - #[inline] - fn cmp(&self, other: &~[T]) -> Ordering { cmp(*self, *other) } -} - -#[cfg(not(test))] -impl TotalOrd for @[T] { - #[inline] - fn cmp(&self, other: &@[T]) -> Ordering { cmp(*self, *other) } -} - -fn lt(a: &[T], b: &[T]) -> bool { - let (a_len, b_len) = (a.len(), b.len()); - let end = uint::min(a_len, b_len); - - let mut i = 0; - while i < end { - let (c_a, c_b) = (&a[i], &b[i]); - if *c_a < *c_b { return true; } - if *c_a > *c_b { return false; } - i += 1; + impl TotalEq for ~[T] { + #[inline] + fn equals(&self, other: &~[T]) -> bool { self.as_slice().equals(&other.as_slice()) } } - a_len < b_len -} - -fn le(a: &[T], b: &[T]) -> bool { !lt(b, a) } -fn ge(a: &[T], b: &[T]) -> bool { !lt(a, b) } -fn gt(a: &[T], b: &[T]) -> bool { lt(b, a) } - -#[cfg(not(test))] -impl<'self,T:Ord> Ord for &'self [T] { - #[inline] - fn lt(&self, other: & &'self [T]) -> bool { lt((*self), (*other)) } - #[inline] - fn le(&self, other: & &'self [T]) -> bool { le((*self), (*other)) } - #[inline] - fn ge(&self, other: & &'self [T]) -> bool { ge((*self), (*other)) } - #[inline] - fn gt(&self, other: & &'self [T]) -> bool { gt((*self), (*other)) } -} - -#[cfg(not(test))] -impl Ord for ~[T] { - #[inline] - fn lt(&self, other: &~[T]) -> bool { lt((*self), (*other)) } - #[inline] - fn le(&self, other: &~[T]) -> bool { le((*self), (*other)) } - #[inline] - fn ge(&self, other: &~[T]) -> bool { ge((*self), (*other)) } - #[inline] - fn gt(&self, other: &~[T]) -> bool { gt((*self), (*other)) } -} - -#[cfg(not(test))] -impl Ord for @[T] { - #[inline] - fn lt(&self, other: &@[T]) -> bool { lt((*self), (*other)) } - #[inline] - fn le(&self, other: &@[T]) -> bool { le((*self), (*other)) } - #[inline] - fn ge(&self, other: &@[T]) -> bool { ge((*self), (*other)) } - #[inline] - fn gt(&self, other: &@[T]) -> bool { gt((*self), (*other)) } -} - -#[cfg(not(test))] -impl<'self,T:Copy> Add<&'self [T], ~[T]> for ~[T] { - #[inline] - fn add(&self, rhs: & &'self [T]) -> ~[T] { - append(copy *self, (*rhs)) + impl TotalEq for @[T] { + #[inline] + fn equals(&self, other: &@[T]) -> bool { self.as_slice().equals(&other.as_slice()) } } + + impl<'self,T:Eq, V: Vector> Equiv for &'self [T] { + #[inline] + fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() } + } + + impl<'self,T:Eq, V: Vector> Equiv for ~[T] { + #[inline] + fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() } + } + + impl<'self,T:Eq, V: Vector> Equiv for @[T] { + #[inline] + fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() } + } + + impl<'self,T:TotalOrd> TotalOrd for &'self [T] { + fn cmp(&self, other: & &'self [T]) -> Ordering { + for self.iter().zip(other.iter()).advance |(s,o)| { + match s.cmp(o) { + Equal => {}, + non_eq => { return non_eq; } + } + } + self.len().cmp(&other.len()) + } + } + + impl TotalOrd for ~[T] { + #[inline] + fn cmp(&self, other: &~[T]) -> Ordering { self.as_slice().cmp(&other.as_slice()) } + } + + impl TotalOrd for @[T] { + #[inline] + fn cmp(&self, other: &@[T]) -> Ordering { self.as_slice().cmp(&other.as_slice()) } + } + + impl<'self,T:Ord> Ord for &'self [T] { + fn lt(&self, other: & &'self [T]) -> bool { + for self.iter().zip(other.iter()).advance |(s,o)| { + if *s < *o { return true; } + if *s > *o { return false; } + } + self.len() < other.len() + } + #[inline] + fn le(&self, other: & &'self [T]) -> bool { !(*other < *self) } + #[inline] + fn ge(&self, other: & &'self [T]) -> bool { !(*self < *other) } + #[inline] + fn gt(&self, other: & &'self [T]) -> bool { *other < *self } + } + + impl Ord for ~[T] { + #[inline] + fn lt(&self, other: &~[T]) -> bool { self.as_slice() < other.as_slice() } + #[inline] + fn le(&self, other: &~[T]) -> bool { self.as_slice() <= other.as_slice() } + #[inline] + fn ge(&self, other: &~[T]) -> bool { self.as_slice() >= other.as_slice() } + #[inline] + fn gt(&self, other: &~[T]) -> bool { self.as_slice() > other.as_slice() } + } + + impl Ord for @[T] { + #[inline] + fn lt(&self, other: &@[T]) -> bool { self.as_slice() < other.as_slice() } + #[inline] + fn le(&self, other: &@[T]) -> bool { self.as_slice() <= other.as_slice() } + #[inline] + fn ge(&self, other: &@[T]) -> bool { self.as_slice() >= other.as_slice() } + #[inline] + fn gt(&self, other: &@[T]) -> bool { self.as_slice() > other.as_slice() } + } + + impl<'self,T:Copy, V: Vector> Add for &'self [T] { + #[inline] + fn add(&self, rhs: &V) -> ~[T] { + let mut res = self.to_owned(); + res.push_all(rhs.as_slice()); + res + } + } + impl> Add for ~[T] { + #[inline] + fn add(&self, rhs: &V) -> ~[T] { + let mut res = self.to_owned(); + res.push_all(rhs.as_slice()); + res + } + } +} + +#[cfg(test)] +pub mod traits {} + +/// Any vector that can be represented as a slice. +pub trait Vector { + /// Work with `self` as a slice. + fn as_slice<'a>(&'a self) -> &'a [T]; +} +impl<'self,T> Vector for &'self [T] { + #[inline(always)] + fn as_slice<'a>(&'a self) -> &'a [T] { *self } +} +impl Vector for ~[T] { + #[inline(always)] + fn as_slice<'a>(&'a self) -> &'a [T] { let v: &'a [T] = *self; v } +} +impl Vector for @[T] { + #[inline(always)] + fn as_slice<'a>(&'a self) -> &'a [T] { let v: &'a [T] = *self; v } } impl<'self, T> Container for &'self [T] { diff --git a/src/test/bench/task-perf-alloc-unwind.rs b/src/test/bench/task-perf-alloc-unwind.rs index e245ab894f5b..abc44dfbc9bb 100644 --- a/src/test/bench/task-perf-alloc-unwind.rs +++ b/src/test/bench/task-perf-alloc-unwind.rs @@ -96,7 +96,7 @@ fn recurse_or_fail(depth: int, st: Option) { fn_box: || @Cons((), fn_box()), tuple: (@Cons((), st.tuple.first()), ~Cons((), @*st.tuple.second())), - vec: st.vec + [@Cons((), *st.vec.last())], + vec: st.vec + &[@Cons((), *st.vec.last())], res: r(@Cons((), st.res._l)) } } From 944d904ad4b4fdef90a2f2267fac206de205f3a0 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Wed, 3 Jul 2013 14:54:11 +1000 Subject: [PATCH 28/93] Convert vec::{split, splitn, rsplit, rsplitn} to external iterators. --- src/libstd/vec.rs | 425 +++++++++++++++++----------------------------- 1 file changed, 160 insertions(+), 265 deletions(-) diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index b702a1c7281e..53a7f71221a4 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -173,105 +173,70 @@ pub fn build_sized_opt(size: Option, build_sized(size.get_or_default(4), builder) } -// Accessors - -/// Copies - -/// Split the vector `v` by applying each element against the predicate `f`. -pub fn split(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] { - let ln = v.len(); - if (ln == 0u) { return ~[] } - - let mut start = 0u; - let mut result = ~[]; - while start < ln { - match v.slice(start, ln).iter().position_(|t| f(t)) { - None => break, - Some(i) => { - result.push(v.slice(start, start + i).to_owned()); - start += i + 1u; - } - } - } - result.push(v.slice(start, ln).to_owned()); - result +/// An iterator over the slices of a vector separated by elements that +/// match a predicate function. +pub struct VecSplitIterator<'self, T> { + priv v: &'self [T], + priv n: uint, + priv pred: &'self fn(t: &T) -> bool, + priv finished: bool } -/** - * Split the vector `v` by applying each element against the predicate `f` up - * to `n` times. - */ -pub fn splitn(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] { - let ln = v.len(); - if (ln == 0u) { return ~[] } +impl<'self, T> Iterator<&'self [T]> for VecSplitIterator<'self, T> { + fn next(&mut self) -> Option<&'self [T]> { + if self.finished { return None; } - let mut start = 0u; - let mut count = n; - let mut result = ~[]; - while start < ln && count > 0u { - match v.slice(start, ln).iter().position_(|t| f(t)) { - None => break, - Some(i) => { - result.push(v.slice(start, start + i).to_owned()); - // Make sure to skip the separator. - start += i + 1u; - count -= 1u; + if self.n == 0 { + self.finished = true; + return Some(self.v); + } + + match self.v.iter().position_(|x| (self.pred)(x)) { + None => { + self.finished = true; + Some(self.v) + } + Some(idx) => { + let ret = Some(self.v.slice(0, idx)); + self.v = self.v.slice(idx + 1, self.v.len()); + self.n -= 1; + ret } } } - result.push(v.slice(start, ln).to_owned()); - result } -/** - * Reverse split the vector `v` by applying each element against the predicate - * `f`. - */ -pub fn rsplit(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] { - let ln = v.len(); - if (ln == 0) { return ~[] } - - let mut end = ln; - let mut result = ~[]; - while end > 0 { - match v.slice(0, end).rposition(|t| f(t)) { - None => break, - Some(i) => { - result.push(v.slice(i + 1, end).to_owned()); - end = i; - } - } - } - result.push(v.slice(0u, end).to_owned()); - result.reverse(); - result +/// An iterator over the slices of a vector separated by elements that +/// match a predicate function, from back to front. +pub struct VecRSplitIterator<'self, T> { + priv v: &'self [T], + priv n: uint, + priv pred: &'self fn(t: &T) -> bool, + priv finished: bool } -/** - * Reverse split the vector `v` by applying each element against the predicate - * `f` up to `n times. - */ -pub fn rsplitn(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] { - let ln = v.len(); - if (ln == 0u) { return ~[] } +impl<'self, T> Iterator<&'self [T]> for VecRSplitIterator<'self, T> { + fn next(&mut self) -> Option<&'self [T]> { + if self.finished { return None; } - let mut end = ln; - let mut count = n; - let mut result = ~[]; - while end > 0u && count > 0u { - match v.slice(0, end).rposition(|t| f(t)) { - None => break, - Some(i) => { - result.push(v.slice(i + 1u, end).to_owned()); - // Make sure to skip the separator. - end = i; - count -= 1u; + if self.n == 0 { + self.finished = true; + return Some(self.v); + } + + match self.v.rposition(|x| (self.pred)(x)) { + None => { + self.finished = true; + Some(self.v) + } + Some(idx) => { + let ret = Some(self.v.slice(idx + 1, self.v.len())); + self.v = self.v.slice(0, idx); + self.n -= 1; + ret } } } - result.push(v.slice(0u, end).to_owned()); - result.reverse(); - result } // Appending @@ -758,6 +723,11 @@ pub trait ImmutableVector<'self, T> { fn slice(&self, start: uint, end: uint) -> &'self [T]; fn iter(self) -> VecIterator<'self, T>; fn rev_iter(self) -> VecRevIterator<'self, T>; + fn split_iter(self, pred: &'self fn(&T) -> bool) -> VecSplitIterator<'self, T>; + fn splitn_iter(self, n: uint, pred: &'self fn(&T) -> bool) -> VecSplitIterator<'self, T>; + fn rsplit_iter(self, pred: &'self fn(&T) -> bool) -> VecRSplitIterator<'self, T>; + fn rsplitn_iter(self, n: uint, pred: &'self fn(&T) -> bool) -> VecRSplitIterator<'self, T>; + fn head(&self) -> &'self T; fn head_opt(&self) -> Option<&'self T>; fn tail(&self) -> &'self [T]; @@ -808,6 +778,45 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { } } + /// Returns an iterator over the subslices of the vector which are + /// separated by elements that match `pred`. + #[inline] + fn split_iter(self, pred: &'self fn(&T) -> bool) -> VecSplitIterator<'self, T> { + self.splitn_iter(uint::max_value, pred) + } + /// Returns an iterator over the subslices of the vector which are + /// separated by elements that match `pred`, limited to splitting + /// at most `n` times. + #[inline] + fn splitn_iter(self, n: uint, pred: &'self fn(&T) -> bool) -> VecSplitIterator<'self, T> { + VecSplitIterator { + v: self, + n: n, + pred: pred, + finished: false + } + } + /// Returns an iterator over the subslices of the vector which are + /// separated by elements that match `pred`. This starts at the + /// end of the vector and works backwards. + #[inline] + fn rsplit_iter(self, pred: &'self fn(&T) -> bool) -> VecRSplitIterator<'self, T> { + self.rsplitn_iter(uint::max_value, pred) + } + /// Returns an iterator over the subslices of the vector which are + /// separated by elements that match `pred` limited to splitting + /// at most `n` times. This starts at the end of the vector and + /// works backwards. + #[inline] + fn rsplitn_iter(self, n: uint, pred: &'self fn(&T) -> bool) -> VecRSplitIterator<'self, T> { + VecRSplitIterator { + v: self, + n: n, + pred: pred, + finished: false + } + } + /// Returns the first element of a vector, failing if the vector is empty. #[inline] fn head(&self) -> &'self T { @@ -2614,50 +2623,6 @@ mod tests { assert!(v3.is_empty()); } - #[test] - fn test_split() { - fn f(x: &int) -> bool { *x == 3 } - - assert_eq!(split([], f), ~[]); - assert_eq!(split([1, 2], f), ~[~[1, 2]]); - assert_eq!(split([3, 1, 2], f), ~[~[], ~[1, 2]]); - assert_eq!(split([1, 2, 3], f), ~[~[1, 2], ~[]]); - assert_eq!(split([1, 2, 3, 4, 3, 5], f), ~[~[1, 2], ~[4], ~[5]]); - } - - #[test] - fn test_splitn() { - fn f(x: &int) -> bool { *x == 3 } - - assert_eq!(splitn([], 1u, f), ~[]); - assert_eq!(splitn([1, 2], 1u, f), ~[~[1, 2]]); - assert_eq!(splitn([3, 1, 2], 1u, f), ~[~[], ~[1, 2]]); - assert_eq!(splitn([1, 2, 3], 1u, f), ~[~[1, 2], ~[]]); - assert!(splitn([1, 2, 3, 4, 3, 5], 1u, f) == - ~[~[1, 2], ~[4, 3, 5]]); - } - - #[test] - fn test_rsplit() { - fn f(x: &int) -> bool { *x == 3 } - - assert_eq!(rsplit([], f), ~[]); - assert_eq!(rsplit([1, 2], f), ~[~[1, 2]]); - assert_eq!(rsplit([1, 2, 3], f), ~[~[1, 2], ~[]]); - assert!(rsplit([1, 2, 3, 4, 3, 5], f) == - ~[~[1, 2], ~[4], ~[5]]); - } - - #[test] - fn test_rsplitn() { - fn f(x: &int) -> bool { *x == 3 } - - assert_eq!(rsplitn([], 1u, f), ~[]); - assert_eq!(rsplitn([1, 2], 1u, f), ~[~[1, 2]]); - assert_eq!(rsplitn([1, 2, 3], 1u, f), ~[~[1, 2], ~[]]); - assert_eq!(rsplitn([1, 2, 3, 4, 3, 5], 1u, f), ~[~[1, 2, 3, 4], ~[5]]); - } - #[test] fn test_partition() { assert_eq!((~[]).partition(|x: &int| *x < 3), (~[], ~[])); @@ -2823,142 +2788,6 @@ mod tests { }; } - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_split_fail_ret_true() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do split(v) |_elt| { - if i == 2 { - fail!() - } - i += 1; - - true - }; - } - - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_split_fail_ret_false() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do split(v) |_elt| { - if i == 2 { - fail!() - } - i += 1; - - false - }; - } - - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_splitn_fail_ret_true() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do splitn(v, 100) |_elt| { - if i == 2 { - fail!() - } - i += 1; - - true - }; - } - - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_splitn_fail_ret_false() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do split(v) |_elt| { - if i == 2 { - fail!() - } - i += 1; - - false - }; - } - - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_rsplit_fail_ret_true() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do rsplit(v) |_elt| { - if i == 2 { - fail!() - } - i += 1; - - true - }; - } - - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_rsplit_fail_ret_false() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do rsplit(v) |_elt| { - if i == 2 { - fail!() - } - i += 1; - - false - }; - } - - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_rsplitn_fail_ret_true() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do rsplitn(v, 100) |_elt| { - if i == 2 { - fail!() - } - i += 1; - - true - }; - } - - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_rsplitn_fail_ret_false() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do rsplitn(v, 100) |_elt| { - if i == 2 { - fail!() - } - i += 1; - - false - }; - } - #[test] #[ignore(windows)] #[should_fail] @@ -3140,6 +2969,72 @@ mod tests { assert_eq!(xs.consume_rev_iter().fold(0, |a: uint, b: uint| 10*a + b), 54321); } + #[test] + fn test_split_iterator() { + let xs = &[1i,2,3,4,5]; + + assert_eq!(xs.split_iter(|x| *x % 2 == 0).collect::<~[&[int]]>(), + ~[&[1], &[3], &[5]]); + assert_eq!(xs.split_iter(|x| *x == 1).collect::<~[&[int]]>(), + ~[&[], &[2,3,4,5]]); + assert_eq!(xs.split_iter(|x| *x == 5).collect::<~[&[int]]>(), + ~[&[1,2,3,4], &[]]); + assert_eq!(xs.split_iter(|x| *x == 10).collect::<~[&[int]]>(), + ~[&[1,2,3,4,5]]); + assert_eq!(xs.split_iter(|_| true).collect::<~[&[int]]>(), + ~[&[], &[], &[], &[], &[], &[]]); + + let xs: &[int] = &[]; + assert_eq!(xs.split_iter(|x| *x == 5).collect::<~[&[int]]>(), ~[&[]]); + } + + #[test] + fn test_splitn_iterator() { + let xs = &[1i,2,3,4,5]; + + assert_eq!(xs.splitn_iter(0, |x| *x % 2 == 0).collect::<~[&[int]]>(), + ~[&[1,2,3,4,5]]); + assert_eq!(xs.splitn_iter(1, |x| *x % 2 == 0).collect::<~[&[int]]>(), + ~[&[1], &[3,4,5]]); + assert_eq!(xs.splitn_iter(3, |_| true).collect::<~[&[int]]>(), + ~[&[], &[], &[], &[4,5]]); + + let xs: &[int] = &[]; + assert_eq!(xs.splitn_iter(1, |x| *x == 5).collect::<~[&[int]]>(), ~[&[]]); + } + + #[test] + fn test_rsplit_iterator() { + let xs = &[1i,2,3,4,5]; + + assert_eq!(xs.rsplit_iter(|x| *x % 2 == 0).collect::<~[&[int]]>(), + ~[&[5], &[3], &[1]]); + assert_eq!(xs.rsplit_iter(|x| *x == 1).collect::<~[&[int]]>(), + ~[&[2,3,4,5], &[]]); + assert_eq!(xs.rsplit_iter(|x| *x == 5).collect::<~[&[int]]>(), + ~[&[], &[1,2,3,4]]); + assert_eq!(xs.rsplit_iter(|x| *x == 10).collect::<~[&[int]]>(), + ~[&[1,2,3,4,5]]); + + let xs: &[int] = &[]; + assert_eq!(xs.rsplit_iter(|x| *x == 5).collect::<~[&[int]]>(), ~[&[]]); + } + + #[test] + fn test_rsplitn_iterator() { + let xs = &[1,2,3,4,5]; + + assert_eq!(xs.rsplitn_iter(0, |x| *x % 2 == 0).collect::<~[&[int]]>(), + ~[&[1,2,3,4,5]]); + assert_eq!(xs.rsplitn_iter(1, |x| *x % 2 == 0).collect::<~[&[int]]>(), + ~[&[5], &[1,2,3]]); + assert_eq!(xs.rsplitn_iter(3, |_| true).collect::<~[&[int]]>(), + ~[&[], &[], &[], &[1,2]]); + + let xs: &[int] = &[]; + assert_eq!(xs.rsplitn_iter(1, |x| *x == 5).collect::<~[&[int]]>(), ~[&[]]); + } + #[test] fn test_move_from() { let mut a = [1,2,3,4,5]; From a732a2daffefffb1b292c26810bec3fbb4a0b9f9 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Wed, 3 Jul 2013 15:47:58 +1000 Subject: [PATCH 29/93] Convert vec::windowed to an external iterator, and add an n-at-a-time chunk iterator. --- src/libstd/vec.rs | 177 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 132 insertions(+), 45 deletions(-) diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 53a7f71221a4..f19f917ee474 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -452,27 +452,46 @@ pub fn each_permutation(values: &[T], fun: &fn(perm : &[T]) -> bool) -> } } -/** - * Iterate over all contiguous windows of length `n` of the vector `v`. - * - * # Example - * - * Print the adjacent pairs of a vector (i.e. `[1,2]`, `[2,3]`, `[3,4]`) - * - * ~~~ {.rust} - * for windowed(2, &[1,2,3,4]) |v| { - * io::println(fmt!("%?", v)); - * } - * ~~~ - * - */ -pub fn windowed<'r, T>(n: uint, v: &'r [T], it: &fn(&'r [T]) -> bool) -> bool { - assert!(1u <= n); - if n > v.len() { return true; } - for uint::range(0, v.len() - n + 1) |i| { - if !it(v.slice(i, i + n)) { return false; } +/// An iterator over the (overlapping) slices of length `size` within +/// a vector. +pub struct VecWindowIter<'self, T> { + priv v: &'self [T], + priv size: uint +} + +impl<'self, T> Iterator<&'self [T]> for VecWindowIter<'self, T> { + fn next(&mut self) -> Option<&'self [T]> { + if self.size > self.v.len() { + None + } else { + let ret = Some(self.v.slice(0, self.size)); + self.v = self.v.slice(1, self.v.len()); + ret + } + } +} + +/// An iterator over a vector in (non-overlapping) chunks (`size` +/// elements at a time). +pub struct VecChunkIter<'self, T> { + priv v: &'self [T], + priv size: uint +} + +impl<'self, T> Iterator<&'self [T]> for VecChunkIter<'self, T> { + fn next(&mut self) -> Option<&'self [T]> { + if self.size == 0 { + None + } else if self.size >= self.v.len() { + // finished + self.size = 0; + Some(self.v) + } else { + let ret = Some(self.v.slice(0, self.size)); + self.v = self.v.slice(self.size, self.v.len()); + ret + } } - return true; } /** @@ -728,6 +747,9 @@ pub trait ImmutableVector<'self, T> { fn rsplit_iter(self, pred: &'self fn(&T) -> bool) -> VecRSplitIterator<'self, T>; fn rsplitn_iter(self, n: uint, pred: &'self fn(&T) -> bool) -> VecRSplitIterator<'self, T>; + fn window_iter(self, size: uint) -> VecWindowIter<'self, T>; + fn chunk_iter(self, size: uint) -> VecChunkIter<'self, T>; + fn head(&self) -> &'self T; fn head_opt(&self) -> Option<&'self T>; fn tail(&self) -> &'self [T]; @@ -817,6 +839,62 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { } } + /** + * Returns an iterator over all contiguous windows of length + * `size`. The windows overlap. If the vector is shorter than + * `size`, the iterator returns no values. + * + * # Failure + * + * Fails if `size` is 0. + * + * # Example + * + * Print the adjacent pairs of a vector (i.e. `[1,2]`, `[2,3]`, + * `[3,4]`): + * + * ~~~ {.rust} + * let v = &[1,2,3,4]; + * for v.window_iter().advance |win| { + * io::println(fmt!("%?", win)); + * } + * ~~~ + * + */ + fn window_iter(self, size: uint) -> VecWindowIter<'self, T> { + assert!(size != 0); + VecWindowIter { v: self, size: size } + } + + /** + * + * Returns an iterator over `size` elements of the vector at a + * time. The chunks do not overlap. If `size` does not divide the + * length of the vector, then the last chunk will not have length + * `size`. + * + * # Failure + * + * Fails if `size` is 0. + * + * # Example + * + * Print the vector two elements at a time (i.e. `[1,2]`, + * `[3,4]`, `[5]`): + * + * ~~~ {.rust} + * let v = &[1,2,3,4,5]; + * for v.chunk_iter().advance |win| { + * io::println(fmt!("%?", win)); + * } + * ~~~ + * + */ + fn chunk_iter(self, size: uint) -> VecChunkIter<'self, T> { + assert!(size != 0); + VecChunkIter { v: self, size: size } + } + /// Returns the first element of a vector, failing if the vector is empty. #[inline] fn head(&self) -> &'self T { @@ -2663,31 +2741,6 @@ mod tests { assert_eq!([&[1], &[2], &[3]].connect_vec(&0), ~[1, 0, 2, 0, 3]); } - #[test] - fn test_windowed () { - fn t(n: uint, expected: &[&[int]]) { - let mut i = 0; - for windowed(n, [1,2,3,4,5,6]) |v| { - assert_eq!(v, expected[i]); - i += 1; - } - - // check that we actually iterated the right number of times - assert_eq!(i, expected.len()); - } - t(3, &[&[1,2,3],&[2,3,4],&[3,4,5],&[4,5,6]]); - t(4, &[&[1,2,3,4],&[2,3,4,5],&[3,4,5,6]]); - t(7, &[]); - t(8, &[]); - } - - #[test] - #[should_fail] - #[ignore(cfg(windows))] - fn test_windowed_() { - for windowed (0u, [1u,2u,3u,4u,5u,6u]) |_v| {} - } - #[test] fn test_unshift() { let mut x = ~[1, 2, 3]; @@ -3035,6 +3088,40 @@ mod tests { assert_eq!(xs.rsplitn_iter(1, |x| *x == 5).collect::<~[&[int]]>(), ~[&[]]); } + #[test] + fn test_window_iterator() { + let v = &[1i,2,3,4]; + + assert_eq!(v.window_iter(2).collect::<~[&[int]]>(), ~[&[1,2], &[2,3], &[3,4]]); + assert_eq!(v.window_iter(3).collect::<~[&[int]]>(), ~[&[1i,2,3], &[2,3,4]]); + assert!(v.window_iter(6).next().is_none()); + } + + #[test] + #[should_fail] + #[ignore(cfg(windows))] + fn test_window_iterator_0() { + let v = &[1i,2,3,4]; + let _it = v.window_iter(0); + } + + #[test] + fn test_chunk_iterator() { + let v = &[1i,2,3,4,5]; + + assert_eq!(v.chunk_iter(2).collect::<~[&[int]]>(), ~[&[1i,2], &[3,4], &[5]]); + assert_eq!(v.chunk_iter(3).collect::<~[&[int]]>(), ~[&[1i,2,3], &[4,5]]); + assert_eq!(v.chunk_iter(6).collect::<~[&[int]]>(), ~[&[1i,2,3,4,5]]); + } + + #[test] + #[should_fail] + #[ignore(cfg(windows))] + fn test_chunk_iterator_0() { + let v = &[1i,2,3,4]; + let _it = v.chunk_iter(0); + } + #[test] fn test_move_from() { let mut a = [1,2,3,4,5]; From cdea73cf5b94784fdc910ab23d5d3455c868d247 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Wed, 3 Jul 2013 16:34:17 +1000 Subject: [PATCH 30/93] Convert vec::{as_imm_buf, as_mut_buf} to methods. --- src/libextra/flate.rs | 4 +- src/libextra/par.rs | 2 +- src/libextra/uv_ll.rs | 4 +- src/librustc/middle/trans/build.rs | 4 +- src/librustc/middle/trans/common.rs | 8 +- src/libstd/io.rs | 6 +- src/libstd/os.rs | 10 +- src/libstd/ptr.rs | 2 +- src/libstd/rand.rs | 4 +- src/libstd/rt/uv/mod.rs | 3 +- src/libstd/run.rs | 8 +- src/libstd/str.rs | 7 +- src/libstd/vec.rs | 111 +++++++++--------- .../bug-2470-bounds-check-overflow.rs | 3 +- 14 files changed, 90 insertions(+), 86 deletions(-) diff --git a/src/libextra/flate.rs b/src/libextra/flate.rs index f249feeb4403..88c61e60d86b 100644 --- a/src/libextra/flate.rs +++ b/src/libextra/flate.rs @@ -45,7 +45,7 @@ static LZ_NORM : c_int = 0x80; // LZ with 128 probes, "normal" static LZ_BEST : c_int = 0xfff; // LZ with 4095 probes, "best" pub fn deflate_bytes(bytes: &[u8]) -> ~[u8] { - do vec::as_imm_buf(bytes) |b, len| { + do bytes.as_imm_buf |b, len| { unsafe { let mut outsz : size_t = 0; let res = @@ -63,7 +63,7 @@ pub fn deflate_bytes(bytes: &[u8]) -> ~[u8] { } pub fn inflate_bytes(bytes: &[u8]) -> ~[u8] { - do vec::as_imm_buf(bytes) |b, len| { + do bytes.as_imm_buf |b, len| { unsafe { let mut outsz : size_t = 0; let res = diff --git a/src/libextra/par.rs b/src/libextra/par.rs index da046f6b5ce7..d56f7b32ae7d 100644 --- a/src/libextra/par.rs +++ b/src/libextra/par.rs @@ -53,7 +53,7 @@ fn map_slices( info!("spawning tasks"); while base < len { let end = uint::min(len, base + items_per_task); - do vec::as_imm_buf(xs) |p, _len| { + do xs.as_imm_buf |p, _len| { let f = f(); let base = base; let f = do future_spawn() || { diff --git a/src/libextra/uv_ll.rs b/src/libextra/uv_ll.rs index db960f334fdc..69ff10078407 100644 --- a/src/libextra/uv_ll.rs +++ b/src/libextra/uv_ll.rs @@ -1046,7 +1046,7 @@ pub unsafe fn ip4_name(src: &sockaddr_in) -> ~str { // ipv4 addr max size: 15 + 1 trailing null byte let dst: ~[u8] = ~[0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8, 0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8]; - do vec::as_imm_buf(dst) |dst_buf, size| { + do dst.as_imm_buf |dst_buf, size| { rust_uv_ip4_name(to_unsafe_ptr(src), dst_buf, size as libc::size_t); // seems that checking the result of uv_ip4_name @@ -1066,7 +1066,7 @@ pub unsafe fn ip6_name(src: &sockaddr_in6) -> ~str { 0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8, 0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8, 0u8,0u8,0u8,0u8,0u8,0u8]; - do vec::as_imm_buf(dst) |dst_buf, size| { + do dst.as_imm_buf |dst_buf, size| { let src_unsafe_ptr = to_unsafe_ptr(src); let result = rust_uv_ip6_name(src_unsafe_ptr, dst_buf, size as libc::size_t); diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index 8535c84c5cb5..811138c6dbdd 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -565,7 +565,7 @@ pub fn LoadRangeAssert(cx: block, PointerVal: ValueRef, lo: c_ulonglong, let min = llvm::LLVMConstInt(t, lo, signed); let max = llvm::LLVMConstInt(t, hi, signed); - do vec::as_imm_buf([min, max]) |ptr, len| { + do [min, max].as_imm_buf |ptr, len| { llvm::LLVMSetMetadata(value, lib::llvm::MD_range as c_uint, llvm::LLVMMDNodeInContext(cx.fcx.ccx.llcx, ptr, len as c_uint)); @@ -942,7 +942,7 @@ pub fn Call(cx: block, Fn: ValueRef, Args: &[ValueRef]) -> ValueRef { cx.val_to_str(Fn), Args.map(|arg| cx.val_to_str(*arg))); - do vec::as_imm_buf(Args) |ptr, len| { + do Args.as_imm_buf |ptr, len| { llvm::LLVMBuildCall(B(cx), Fn, ptr, len as c_uint, noname()) } } diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 5b3052a1e1f4..865fb26b9455 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -774,7 +774,7 @@ pub fn C_zero_byte_arr(size: uint) -> ValueRef { pub fn C_struct(elts: &[ValueRef]) -> ValueRef { unsafe { - do vec::as_imm_buf(elts) |ptr, len| { + do elts.as_imm_buf |ptr, len| { llvm::LLVMConstStructInContext(base::task_llcx(), ptr, len as c_uint, False) } } @@ -782,7 +782,7 @@ pub fn C_struct(elts: &[ValueRef]) -> ValueRef { pub fn C_packed_struct(elts: &[ValueRef]) -> ValueRef { unsafe { - do vec::as_imm_buf(elts) |ptr, len| { + do elts.as_imm_buf |ptr, len| { llvm::LLVMConstStructInContext(base::task_llcx(), ptr, len as c_uint, True) } } @@ -790,7 +790,7 @@ pub fn C_packed_struct(elts: &[ValueRef]) -> ValueRef { pub fn C_named_struct(T: Type, elts: &[ValueRef]) -> ValueRef { unsafe { - do vec::as_imm_buf(elts) |ptr, len| { + do elts.as_imm_buf |ptr, len| { llvm::LLVMConstNamedStruct(T.to_ref(), ptr, len as c_uint) } } @@ -826,7 +826,7 @@ pub fn get_param(fndecl: ValueRef, param: uint) -> ValueRef { pub fn const_get_elt(cx: &CrateContext, v: ValueRef, us: &[c_uint]) -> ValueRef { unsafe { - let r = do vec::as_imm_buf(us) |p, len| { + let r = do us.as_imm_buf |p, len| { llvm::LLVMConstExtractValue(v, p, len as c_uint) }; diff --git a/src/libstd/io.rs b/src/libstd/io.rs index bdcad15f45c4..38826dd411b6 100644 --- a/src/libstd/io.rs +++ b/src/libstd/io.rs @@ -917,7 +917,7 @@ fn convert_whence(whence: SeekStyle) -> i32 { impl Reader for *libc::FILE { fn read(&self, bytes: &mut [u8], len: uint) -> uint { unsafe { - do vec::as_mut_buf(bytes) |buf_p, buf_len| { + do bytes.as_mut_buf |buf_p, buf_len| { assert!(buf_len >= len); let count = libc::fread(buf_p as *mut c_void, 1u as size_t, @@ -1152,7 +1152,7 @@ impl Writer for Wrapper { impl Writer for *libc::FILE { fn write(&self, v: &[u8]) { unsafe { - do vec::as_imm_buf(v) |vbuf, len| { + do v.as_imm_buf |vbuf, len| { let nout = libc::fwrite(vbuf as *c_void, 1, len as size_t, @@ -1203,7 +1203,7 @@ impl Writer for fd_t { fn write(&self, v: &[u8]) { unsafe { let mut count = 0u; - do vec::as_imm_buf(v) |vbuf, len| { + do v.as_imm_buf |vbuf, len| { while count < len { let vb = ptr::offset(vbuf, count) as *c_void; let nout = libc::write(*self, vb, len as size_t); diff --git a/src/libstd/os.rs b/src/libstd/os.rs index c994bbf6fa49..be0c504885b3 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -92,7 +92,7 @@ pub fn as_c_charp(s: &str, f: &fn(*c_char) -> T) -> T { pub fn fill_charp_buf(f: &fn(*mut c_char, size_t) -> bool) -> Option<~str> { let mut buf = vec::from_elem(TMPBUF_SZ, 0u8 as c_char); - do vec::as_mut_buf(buf) |b, sz| { + do buf.as_mut_buf |b, sz| { if f(b, sz as size_t) { unsafe { Some(str::raw::from_buf(b as *u8)) @@ -122,7 +122,7 @@ pub mod win32 { while !done { let mut k: DWORD = 0; let mut buf = vec::from_elem(n as uint, 0u16); - do vec::as_mut_buf(buf) |b, _sz| { + do buf.as_mut_buf |b, _sz| { k = f(b, TMPBUF_SZ as DWORD); if k == (0 as DWORD) { done = true; @@ -147,7 +147,7 @@ pub mod win32 { let mut t = s.to_utf16(); // Null terminate before passing on. t.push(0u16); - vec::as_imm_buf(t, |buf, _len| f(buf)) + t.as_imm_buf(|buf, _len| f(buf)) } } @@ -937,7 +937,7 @@ pub fn copy_file(from: &Path, to: &Path) -> bool { let mut done = false; let mut ok = true; while !done { - do vec::as_mut_buf(buf) |b, _sz| { + do buf.as_mut_buf |b, _sz| { let nread = libc::fread(b as *mut c_void, 1u as size_t, bufsize as size_t, istream); @@ -1683,7 +1683,7 @@ mod tests { let s = ~"hello"; let mut buf = s.as_bytes_with_null().to_owned(); let len = buf.len(); - do vec::as_mut_buf(buf) |b, _len| { + do buf.as_mut_buf |b, _len| { assert_eq!(libc::fwrite(b as *c_void, 1u as size_t, (s.len() + 1u) as size_t, ostream), len as size_t) diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs index 473f56ddd798..aee6f1bd204e 100644 --- a/src/libstd/ptr.rs +++ b/src/libstd/ptr.rs @@ -406,7 +406,7 @@ pub mod ptr_tests { do str::as_c_str(s1) |p1| { do str::as_c_str(s2) |p2| { let v = ~[p0, p1, p2, null()]; - do vec::as_imm_buf(v) |vp, len| { + do v.as_imm_buf |vp, len| { assert_eq!(unsafe { buf_len(vp) }, 3u); assert_eq!(len, 4u); } diff --git a/src/libstd/rand.rs b/src/libstd/rand.rs index 5782822bc2b7..5054763d742b 100644 --- a/src/libstd/rand.rs +++ b/src/libstd/rand.rs @@ -830,7 +830,7 @@ pub fn seed() -> ~[u8] { unsafe { let n = rustrt::rand_seed_size() as uint; let mut s = vec::from_elem(n, 0_u8); - do vec::as_mut_buf(s) |p, sz| { + do s.as_mut_buf |p, sz| { rustrt::rand_gen_seed(p, sz as size_t) } s @@ -1087,7 +1087,7 @@ mod tests { for 10.times { unsafe { let seed = super::seed(); - let rt_rng = do vec::as_imm_buf(seed) |p, sz| { + let rt_rng = do seed.as_imm_buf |p, sz| { rustrt::rand_new_seeded(p, sz as size_t) }; let mut rng = IsaacRng::new_seeded(seed); diff --git a/src/libstd/rt/uv/mod.rs b/src/libstd/rt/uv/mod.rs index f50efc079a7c..092d73662026 100644 --- a/src/libstd/rt/uv/mod.rs +++ b/src/libstd/rt/uv/mod.rs @@ -40,6 +40,7 @@ use str::raw::from_c_str; use to_str::ToStr; use ptr::RawPtr; use vec; +use vec::ImmutableVector; use ptr; use str; use libc::{c_void, c_int, size_t, malloc, free}; @@ -300,7 +301,7 @@ pub fn vec_to_uv_buf(v: ~[u8]) -> Buf { unsafe { let data = malloc(v.len() as size_t) as *u8; assert!(data.is_not_null()); - do vec::as_imm_buf(v) |b, l| { + do v.as_imm_buf |b, l| { let data = data as *mut u8; ptr::copy_memory(data, b, l) } diff --git a/src/libstd/run.rs b/src/libstd/run.rs index 9e5def253c7e..df15111a91f4 100644 --- a/src/libstd/run.rs +++ b/src/libstd/run.rs @@ -24,7 +24,7 @@ use prelude::*; use ptr; use str; use task; -use vec; +use vec::ImmutableVector; /** * A value representing a child process. @@ -703,7 +703,7 @@ fn with_argv(prog: &str, args: &[~str], argptrs.push(str::as_c_str(*t, |b| b)); } argptrs.push(ptr::null()); - vec::as_imm_buf(argptrs, |buf, _len| cb(buf)) + argptrs.as_imm_buf(|buf, _len| cb(buf)) } #[cfg(unix)] @@ -722,7 +722,7 @@ fn with_envp(env: Option<&[(~str, ~str)]>, cb: &fn(*c_void) -> T) -> T { } ptrs.push(ptr::null()); - vec::as_imm_buf(ptrs, |p, _len| + ptrs.as_imm_buf(|p, _len| unsafe { cb(::cast::transmute(p)) } ) } @@ -743,7 +743,7 @@ fn with_envp(env: Option<&[(~str, ~str)]>, cb: &fn(*mut c_void) -> T) -> T { blk.push_all(kv.as_bytes_with_null_consume()); } blk.push(0); - vec::as_imm_buf(blk, |p, _len| + blk.as_imm_buf(|p, _len| unsafe { cb(::cast::transmute(p)) } ) } diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 28162cf5117c..564c58f7097e 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -826,6 +826,7 @@ pub mod raw { use str::raw; use str::{as_buf, is_utf8}; use vec; + use vec::MutableVector; /// Create a Rust string from a null-terminated *u8 buffer pub unsafe fn from_buf(buf: *u8) -> ~str { @@ -841,7 +842,7 @@ pub mod raw { /// Create a Rust string from a *u8 buffer of the given length pub unsafe fn from_buf_len(buf: *u8, len: uint) -> ~str { let mut v: ~[u8] = vec::with_capacity(len + 1); - vec::as_mut_buf(v, |vbuf, _len| { + v.as_mut_buf(|vbuf, _len| { ptr::copy_memory(vbuf, buf as *u8, len) }); vec::raw::set_len(&mut v, len); @@ -863,7 +864,7 @@ pub mod raw { /// Converts a vector of bytes to a new owned string. pub unsafe fn from_bytes(v: &[u8]) -> ~str { - do vec::as_imm_buf(v) |buf, len| { + do v.as_imm_buf |buf, len| { from_buf_len(buf, len) } } @@ -917,7 +918,7 @@ pub mod raw { assert!((end <= n)); let mut v = vec::with_capacity(end - begin + 1u); - do vec::as_imm_buf(v) |vbuf, _vlen| { + do v.as_imm_buf |vbuf, _vlen| { let vbuf = ::cast::transmute_mut_unsafe(vbuf); let src = ptr::offset(sbuf, begin); ptr::copy_memory(vbuf, src, end - begin); diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index f19f917ee474..fb9c47b43733 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -71,7 +71,7 @@ pub fn same_length(xs: &[T], ys: &[U]) -> bool { pub fn from_fn(n_elts: uint, op: &fn(uint) -> T) -> ~[T] { unsafe { let mut v = with_capacity(n_elts); - do as_mut_buf(v) |p, _len| { + do v.as_mut_buf |p, _len| { let mut i: uint = 0u; while i < n_elts { intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)), op(i)); @@ -96,7 +96,7 @@ pub fn from_elem(n_elts: uint, t: T) -> ~[T] { // vec::with_capacity/ptr::set_memory for primitive types. unsafe { let mut v = with_capacity(n_elts); - do as_mut_buf(v) |p, _len| { + do v.as_mut_buf |p, _len| { let mut i = 0u; while i < n_elts { intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)), copy t); @@ -494,40 +494,6 @@ impl<'self, T> Iterator<&'self [T]> for VecChunkIter<'self, T> { } } -/** - * Work with the buffer of a vector. - * - * Allows for unsafe manipulation of vector contents, which is useful for - * foreign interop. - */ -#[inline] -pub fn as_imm_buf(s: &[T], - /* NB---this CANNOT be const, see below */ - f: &fn(*T, uint) -> U) -> U { - - // NB---Do not change the type of s to `&const [T]`. This is - // unsound. The reason is that we are going to create immutable pointers - // into `s` and pass them to `f()`, but in fact they are potentially - // pointing at *mutable memory*. Use `as_const_buf` or `as_mut_buf` - // instead! - - unsafe { - let v : *(*T,uint) = transmute(&s); - let (buf,len) = *v; - f(buf, len / sys::nonzero_size_of::()) - } -} - -/// Similar to `as_imm_buf` but passing a `*mut T` -#[inline] -pub fn as_mut_buf(s: &mut [T], f: &fn(*mut T, uint) -> U) -> U { - unsafe { - let v : *(*mut T,uint) = transmute(&s); - let (buf,len) = *v; - f(buf, len / sys::nonzero_size_of::()) - } -} - // Equality #[cfg(not(test))] @@ -695,13 +661,13 @@ impl<'self, T> Container for &'self [T] { /// Returns true if a vector contains no elements #[inline] fn is_empty(&self) -> bool { - as_imm_buf(*self, |_p, len| len == 0u) + self.as_imm_buf(|_p, len| len == 0u) } /// Returns the length of a vector #[inline] fn len(&self) -> uint { - as_imm_buf(*self, |_p, len| len) + self.as_imm_buf(|_p, len| len) } } @@ -709,13 +675,13 @@ impl Container for ~[T] { /// Returns true if a vector contains no elements #[inline] fn is_empty(&self) -> bool { - as_imm_buf(*self, |_p, len| len == 0u) + self.as_imm_buf(|_p, len| len == 0u) } /// Returns the length of a vector #[inline] fn len(&self) -> uint { - as_imm_buf(*self, |_p, len| len) + self.as_imm_buf(|_p, len| len) } } @@ -765,6 +731,8 @@ pub trait ImmutableVector<'self, T> { fn bsearch(&self, f: &fn(&T) -> Ordering) -> Option; fn map(&self, &fn(t: &T) -> U) -> ~[U]; + + fn as_imm_buf(&self, f: &fn(*T, uint) -> U) -> U; } /// Extension methods for vectors @@ -774,7 +742,7 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { fn slice(&self, start: uint, end: uint) -> &'self [T] { assert!(start <= end); assert!(end <= self.len()); - do as_imm_buf(*self) |p, _len| { + do self.as_imm_buf |p, _len| { unsafe { transmute((ptr::offset(p, start), (end - start) * sys::nonzero_size_of::())) @@ -1007,6 +975,28 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { fn map(&self, f: &fn(t: &T) -> U) -> ~[U] { self.iter().transform(f).collect() } + + /** + * Work with the buffer of a vector. + * + * Allows for unsafe manipulation of vector contents, which is useful for + * foreign interop. + */ + #[inline] + fn as_imm_buf(&self, + /* NB---this CANNOT be const, see below */ + f: &fn(*T, uint) -> U) -> U { + // NB---Do not change the type of s to `&const [T]`. This is + // unsound. The reason is that we are going to create immutable pointers + // into `s` and pass them to `f()`, but in fact they are potentially + // pointing at *mutable memory*. Use `as_mut_buf` instead! + + unsafe { + let v : *(*T,uint) = transmute(self); + let (buf,len) = *v; + f(buf, len / sys::nonzero_size_of::()) + } + } } #[allow(missing_doc)] @@ -1280,7 +1270,7 @@ impl OwnedVector for ~[T] { let new_len = self.len() + rhs.len(); self.reserve(new_len); unsafe { - do as_mut_buf(rhs) |p, len| { + do rhs.as_mut_buf |p, len| { for uint::range(0, len) |i| { let x = ptr::replace_ptr(ptr::mut_offset(p, i), intrinsics::uninit()); @@ -1412,7 +1402,7 @@ impl OwnedVector for ~[T] { /// Shorten a vector, dropping excess elements. fn truncate(&mut self, newlen: uint) { - do as_mut_buf(*self) |p, oldlen| { + do self.as_mut_buf |p, oldlen| { assert!(newlen <= oldlen); unsafe { // This loop is optimized out for non-drop types. @@ -1570,7 +1560,7 @@ impl OwnedEqVector for ~[T] { if self.len() == 0 { return; } let mut last_written = 0; let mut next_to_read = 1; - do as_mut_buf(*self) |p, ln| { + do self.as_mut_buf |p, ln| { // last_written < next_to_read <= ln while next_to_read < ln { // last_written < next_to_read < ln @@ -1624,6 +1614,8 @@ pub trait MutableVector<'self, T> { unsafe fn unsafe_mut_ref(&self, index: uint) -> *mut T; unsafe fn unsafe_set(&self, index: uint, val: T); + + fn as_mut_buf(&self, f: &fn(*mut T, uint) -> U) -> U; } impl<'self,T> MutableVector<'self, T> for &'self mut [T] { @@ -1632,7 +1624,7 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] { fn mut_slice(self, start: uint, end: uint) -> &'self mut [T] { assert!(start <= end); assert!(end <= self.len()); - do as_mut_buf(self) |p, _len| { + do self.as_mut_buf |p, _len| { unsafe { transmute((ptr::mut_offset(p, start), (end - start) * sys::nonzero_size_of::())) @@ -1705,6 +1697,17 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] { unsafe fn unsafe_set(&self, index: uint, val: T) { *self.unsafe_mut_ref(index) = val; } + + /// Similar to `as_imm_buf` but passing a `*mut T` + #[inline] + fn as_mut_buf(&self, f: &fn(*mut T, uint) -> U) -> U { + unsafe { + let v : *(*mut T,uint) = transmute(self); + let (buf,len) = *v; + f(buf, len / sys::nonzero_size_of::()) + } + } + } /// Trait for ~[T] where T is Cloneable @@ -1754,7 +1757,7 @@ pub mod raw { use ptr; use sys; use unstable::intrinsics; - use vec::{UnboxedVecRepr, as_imm_buf, as_mut_buf, with_capacity}; + use vec::{UnboxedVecRepr, with_capacity, ImmutableVector, MutableVector}; use util; /// The internal representation of a (boxed) vector @@ -1842,7 +1845,7 @@ pub mod raw { */ #[inline] pub unsafe fn get(v: &[T], i: uint) -> T { - as_imm_buf(v, |p, _len| copy *ptr::offset(p, i)) + v.as_imm_buf(|p, _len| copy *ptr::offset(p, i)) } /** @@ -1853,7 +1856,7 @@ pub mod raw { #[inline] pub unsafe fn init_elem(v: &mut [T], i: uint, val: T) { let mut box = Some(val); - do as_mut_buf(v) |p, _len| { + do v.as_mut_buf |p, _len| { let box2 = util::replace(&mut box, None); intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)), box2.unwrap()); @@ -1873,7 +1876,7 @@ pub mod raw { pub unsafe fn from_buf_raw(ptr: *T, elts: uint) -> ~[T] { let mut dst = with_capacity(elts); set_len(&mut dst, elts); - as_mut_buf(dst, |p_dst, _len_dst| ptr::copy_memory(p_dst, ptr, elts)); + dst.as_mut_buf(|p_dst, _len_dst| ptr::copy_memory(p_dst, ptr, elts)); dst } @@ -1889,8 +1892,8 @@ pub mod raw { assert!(dst.len() >= count); assert!(src.len() >= count); - do as_mut_buf(dst) |p_dst, _len_dst| { - do as_imm_buf(src) |p_src, _len_src| { + do dst.as_mut_buf |p_dst, _len_dst| { + do src.as_imm_buf |p_src, _len_src| { ptr::copy_memory(p_dst, p_src, count) } } @@ -1914,7 +1917,7 @@ pub mod bytes { impl<'self> MutableByteVector for &'self mut [u8] { #[inline] fn set_memory(self, value: u8) { - do vec::as_mut_buf(self) |p, len| { + do self.as_mut_buf |p, len| { unsafe { ptr::set_memory(p, value, len) }; } } @@ -2920,7 +2923,7 @@ mod tests { #[should_fail] fn test_as_imm_buf_fail() { let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - do as_imm_buf(v) |_buf, _i| { + do v.as_imm_buf |_buf, _i| { fail!() } } @@ -2930,7 +2933,7 @@ mod tests { #[should_fail] fn test_as_mut_buf_fail() { let mut v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - do as_mut_buf(v) |_buf, _i| { + do v.as_mut_buf |_buf, _i| { fail!() } } diff --git a/src/test/run-fail/bug-2470-bounds-check-overflow.rs b/src/test/run-fail/bug-2470-bounds-check-overflow.rs index bd7d86d72953..0fdaf31c5936 100644 --- a/src/test/run-fail/bug-2470-bounds-check-overflow.rs +++ b/src/test/run-fail/bug-2470-bounds-check-overflow.rs @@ -11,7 +11,6 @@ // error-pattern:index out of bounds use std::sys; -use std::vec; fn main() { @@ -22,7 +21,7 @@ fn main() { // huge). let x = ~[1u,2u,3u]; - do vec::as_imm_buf(x) |p, _len| { + do x.as_imm_buf |p, _len| { let base = p as uint; let idx = base / sys::size_of::(); error!("ov1 base = 0x%x", base); From 419a14772a6ae4c61fd275e31dbfceedd0223630 Mon Sep 17 00:00:00 2001 From: Michael Sullivan Date: Mon, 1 Jul 2013 18:38:41 -0700 Subject: [PATCH 31/93] Fix make_mono_id to take into account self types. Closes #7536. --- src/librustc/middle/trans/meth.rs | 14 ++--- src/librustc/middle/trans/monomorphize.rs | 66 +++++++++++++---------- src/test/run-pass/bug-7183-generics.rs | 5 +- 3 files changed, 49 insertions(+), 36 deletions(-) diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 9792e623388d..65271faa7b08 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -641,16 +641,18 @@ pub fn vtable_id(ccx: @mut CrateContext, -> mono_id { match origin { &typeck::vtable_static(impl_id, ref substs, sub_vtables) => { + let psubsts = param_substs { + tys: copy *substs, + vtables: Some(sub_vtables), + self_ty: None, + self_vtable: None + }; + monomorphize::make_mono_id( ccx, impl_id, - *substs, - if sub_vtables.is_empty() { - None - } else { - Some(sub_vtables) - }, None, + &psubsts, None) } diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index ad48c30747ed..1a597e30afd5 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -50,11 +50,13 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, fn_id=%s, \ real_substs=%s, \ vtables=%s, \ + self_vtable=%s, \ impl_did_opt=%s, \ ref_id=%?)", fn_id.repr(ccx.tcx), real_substs.repr(ccx.tcx), vtables.repr(ccx.tcx), + self_vtable.repr(ccx.tcx), impl_did_opt.repr(ccx.tcx), ref_id); @@ -71,7 +73,16 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, for real_substs.tps.iter().advance |s| { assert!(!ty::type_has_params(*s)); } for substs.iter().advance |s| { assert!(!ty::type_has_params(*s)); } let param_uses = type_use::type_uses_for(ccx, fn_id, substs.len()); - let hash_id = make_mono_id(ccx, fn_id, substs, vtables, impl_did_opt, + + let psubsts = @param_substs { + tys: substs, + vtables: vtables, + self_ty: real_substs.self_ty, + self_vtable: self_vtable + }; + + let hash_id = make_mono_id(ccx, fn_id, impl_did_opt, + &*psubsts, Some(param_uses)); if hash_id.params.iter().any_( |p| match *p { mono_precise(_, _) => false, _ => true }) { @@ -80,12 +91,10 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, debug!("monomorphic_fn(\ fn_id=%s, \ - vtables=%s, \ - substs=%s, \ + psubsts=%s, \ hash_id=%?)", fn_id.repr(ccx.tcx), - vtables.repr(ccx.tcx), - substs.repr(ccx.tcx), + psubsts.repr(ccx.tcx), hash_id); match ccx.monomorphized.find(&hash_id) { @@ -142,8 +151,8 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, ast_map::node_struct_ctor(_, i, pt) => (pt, i.ident, i.span) }; - let mono_ty = ty::subst_tps(ccx.tcx, substs, - real_substs.self_ty, llitem_ty); + let mono_ty = ty::subst_tps(ccx.tcx, psubsts.tys, + psubsts.self_ty, llitem_ty); let llfty = type_of_fn_from_ty(ccx, mono_ty); ccx.stats.n_monos += 1; @@ -172,13 +181,6 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, lldecl }; - let psubsts = Some(@param_substs { - tys: substs, - vtables: vtables, - self_ty: real_substs.self_ty, - self_vtable: self_vtable - }); - let lldecl = match map_node { ast_map::node_item(i@@ast::item { node: ast::item_fn(ref decl, _, _, _, ref body), @@ -192,7 +194,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, body, d, no_self, - psubsts, + Some(psubsts), fn_id.node, []); d @@ -202,7 +204,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, } ast_map::node_foreign_item(i, _, _, _) => { let d = mk_lldecl(); - foreign::trans_intrinsic(ccx, d, i, pt, psubsts.get(), i.attrs, + foreign::trans_intrinsic(ccx, d, i, pt, psubsts, i.attrs, ref_id); d } @@ -214,7 +216,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, match v.node.kind { ast::tuple_variant_kind(ref args) => { trans_enum_variant(ccx, enum_item.id, v, /*bad*/copy *args, - this_tv.disr_val, psubsts, d); + this_tv.disr_val, Some(psubsts), d); } ast::struct_variant_kind(_) => ccx.tcx.sess.bug("can't monomorphize struct variants"), @@ -225,13 +227,13 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, // XXX: What should the self type be here? let d = mk_lldecl(); set_inline_hint_if_appr(/*bad*/copy mth.attrs, d); - meth::trans_method(ccx, pt, mth, psubsts, d); + meth::trans_method(ccx, pt, mth, Some(psubsts), d); d } ast_map::node_trait_method(@ast::provided(mth), _, pt) => { let d = mk_lldecl(); set_inline_hint_if_appr(/*bad*/copy mth.attrs, d); - meth::trans_method(ccx, /*bad*/copy *pt, mth, psubsts, d); + meth::trans_method(ccx, /*bad*/copy *pt, mth, Some(psubsts), d); d } ast_map::node_struct_ctor(struct_def, _, _) => { @@ -241,7 +243,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, /*bad*/copy struct_def.fields, struct_def.ctor_id.expect("ast-mapped tuple struct \ didn't have a ctor id"), - psubsts, + Some(psubsts), d); d } @@ -320,26 +322,36 @@ pub fn normalize_for_monomorphization(tcx: ty::ctxt, pub fn make_mono_id(ccx: @mut CrateContext, item: ast::def_id, - substs: &[ty::t], - vtables: Option, impl_did_opt: Option, + substs: ¶m_substs, param_uses: Option<@~[type_use::type_uses]>) -> mono_id { // FIXME (possibly #5801): Need a lot of type hints to get // .collect() to work. - let precise_param_ids: ~[(ty::t, Option<@~[mono_id]>)] = match vtables { + let substs_iter = substs.self_ty.iter().chain_(substs.tys.iter()); + let precise_param_ids: ~[(ty::t, Option<@~[mono_id]>)] = match substs.vtables { Some(vts) => { debug!("make_mono_id vtables=%s substs=%s", - vts.repr(ccx.tcx), substs.repr(ccx.tcx)); - vts.iter().zip(substs.iter()).transform(|(vtable, subst)| { + vts.repr(ccx.tcx), substs.tys.repr(ccx.tcx)); + let self_vtables = substs.self_vtable.map(|vtbl| @~[copy *vtbl]); + let vts_iter = self_vtables.iter().chain_(vts.iter()); + vts_iter.zip(substs_iter).transform(|(vtable, subst)| { let v = vtable.map(|vt| meth::vtable_id(ccx, vt)); (*subst, if !v.is_empty() { Some(@v) } else { None }) }).collect() } - None => substs.iter().transform(|subst| (*subst, None::<@~[mono_id]>)).collect() + None => substs_iter.transform(|subst| (*subst, None::<@~[mono_id]>)).collect() }; + + let param_ids = match param_uses { Some(ref uses) => { - precise_param_ids.iter().zip(uses.iter()).transform(|(id, uses)| { + // param_uses doesn't include a use for the self type. + // We just say it is fully used. + let self_use = + substs.self_ty.map(|_| type_use::use_repr|type_use::use_tydesc); + let uses_iter = self_use.iter().chain_(uses.iter()); + + precise_param_ids.iter().zip(uses_iter).transform(|(id, uses)| { if ccx.sess.no_monomorphic_collapse() { match copy *id { (a, b) => mono_precise(a, b) diff --git a/src/test/run-pass/bug-7183-generics.rs b/src/test/run-pass/bug-7183-generics.rs index 4fc5587e7f36..532b2312a987 100644 --- a/src/test/run-pass/bug-7183-generics.rs +++ b/src/test/run-pass/bug-7183-generics.rs @@ -39,7 +39,6 @@ fn main() { assert_eq!(Some(Some(3)).hi(), ~"something!something!hello: 3"); assert_eq!(None::.hi(), ~"hello - none"); - // These fail because of a bug in monomorphization's ID generation. - //assert_eq!(Some(None::).hi(), ~"something!hello - none"); - //assert_eq!(Some(3).hi(), ~"something!hello: 3"); + assert_eq!(Some(None::).hi(), ~"something!hello - none"); + assert_eq!(Some(3).hi(), ~"something!hello: 3"); } From 7238d5a141745b24d2b78c1bd212974c4335f5ce Mon Sep 17 00:00:00 2001 From: Michael Sullivan Date: Tue, 2 Jul 2013 14:39:25 -0700 Subject: [PATCH 32/93] Make privacy checking on default methods for cross crate structs not fail. Closes #7481. It is unclear to me that the way method call privacy checking is done makes any sense, though. It is only performed if the type is a struct... --- src/librustc/middle/privacy.rs | 8 ++++++ .../auxiliary/trait_default_method_xc_aux.rs | 6 ++++ src/test/run-pass/trait-default-method-xc.rs | 28 +++++++++++-------- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 5e544dc06e3d..64ed3b0211d3 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -245,6 +245,14 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, method_id: def_id, name: &ident) = |span, method_id, name| { + // If the method is a default method, we need to use the def_id of + // the default implementation. + // Having to do this this is really unfortunate. + let method_id = match tcx.provided_method_sources.find(&method_id) { + None => method_id, + Some(source) => source.method_id + }; + if method_id.crate == local_crate { let is_private = method_is_private(span, method_id.node); let container_id = local_method_container_id(span, diff --git a/src/test/auxiliary/trait_default_method_xc_aux.rs b/src/test/auxiliary/trait_default_method_xc_aux.rs index 5ee243179df8..7ae648f113a3 100644 --- a/src/test/auxiliary/trait_default_method_xc_aux.rs +++ b/src/test/auxiliary/trait_default_method_xc_aux.rs @@ -1,5 +1,7 @@ #[allow(default_methods)]; +pub struct Something { x: int } + pub trait A { fn f(&self) -> int; fn g(&self) -> int { 10 } @@ -11,6 +13,10 @@ impl A for int { fn f(&self) -> int { 10 } } +impl A for Something { + fn f(&self) -> int { 10 } +} + trait B { fn thing(&self, x: T, y: U) -> (T, U) { (x, y) } } diff --git a/src/test/run-pass/trait-default-method-xc.rs b/src/test/run-pass/trait-default-method-xc.rs index f6c119c4faeb..4eac1a1e7308 100644 --- a/src/test/run-pass/trait-default-method-xc.rs +++ b/src/test/run-pass/trait-default-method-xc.rs @@ -4,16 +4,18 @@ #[allow(default_methods)]; extern mod aux(name = "trait_default_method_xc_aux"); -use aux::{A, B, TestEquality}; +use aux::{A, B, TestEquality, Something}; fn f(i: T) { assert_eq!(i.g(), 10); } +mod stuff { + pub struct thing { x: int } +} -pub struct thing { x: int } -impl A for thing { +impl A for stuff::thing { fn f(&self) -> int { 10 } } @@ -29,8 +31,8 @@ fn neq(lhs: &T, rhs: &T) -> bool { } -impl TestEquality for thing { - fn test_eq(&self, rhs: &thing) -> bool { +impl TestEquality for stuff::thing { + fn test_eq(&self, rhs: &stuff::thing) -> bool { //self.x.test_eq(&rhs.x) eq(&self.x, &rhs.x) } @@ -41,15 +43,17 @@ fn main () { // Some tests of random things f(0); - let a = thing { x: 0 }; - let b = thing { x: 1 }; + let a = stuff::thing { x: 0 }; + let b = stuff::thing { x: 1 }; + let c = Something { x: 1 }; - //assert_eq!(0i.g(), 10); + assert_eq!(0i.g(), 10); assert_eq!(a.g(), 10); assert_eq!(a.h(), 10); + assert_eq!(c.h(), 10); - - //assert_eq!(0i.thing(3.14, 1), (3.14, 1)); + 0i.thing(3.14, 1); + assert_eq!(0i.thing(3.14, 1), (3.14, 1)); assert_eq!(g(0i, 3.14, 1), (3.14, 1)); assert_eq!(g(false, 3.14, 1), (3.14, 1)); @@ -59,8 +63,8 @@ fn main () { // Trying out a real one - //assert!(12.test_neq(&10)); - //assert!(!10.test_neq(&10)); + assert!(12.test_neq(&10)); + assert!(!10.test_neq(&10)); assert!(a.test_neq(&b)); assert!(!a.test_neq(&a)); From 656c8f91435df99b11bfe31be73eba6d8f391870 Mon Sep 17 00:00:00 2001 From: Gareth Smith Date: Wed, 3 Jul 2013 22:16:08 +0100 Subject: [PATCH 33/93] Make the error messages that result from referencing nonexistent traits consistent, and add a test. --- src/librustc/middle/resolve.rs | 46 +++++++++---------- .../compile-fail/resolve-unknown-trait.rs | 20 ++++++++ 2 files changed, 43 insertions(+), 23 deletions(-) create mode 100644 src/test/compile-fail/resolve-unknown-trait.rs diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 8e25f598f365..6ddac371e0c6 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -510,6 +510,13 @@ pub struct NameBindings { value_def: Option, //< Meaning in value namespace. } +/// Ways in which a trait can be referenced +enum TraitReferenceType { + TraitImplementation, // impl SomeTrait for T { ... } + TraitDerivation, // trait T : SomeTrait { ... } + TraitBoundingTypeParameter, // fn f() { ... } +} + impl NameBindings { /// Creates a new module in this set of name bindings. pub fn define_module(@mut self, @@ -3554,23 +3561,7 @@ impl Resolver { // Resolve derived traits. for traits.iter().advance |trt| { - match self.resolve_path(trt.path, TypeNS, true, - visitor) { - None => - self.session.span_err(trt.path.span, - "attempt to derive a \ - nonexistent trait"), - Some(def) => { - // Write a mapping from the trait ID to the - // definition of the trait into the definition - // map. - - debug!("(resolving trait) found trait def: \ - %?", def); - - self.record_def(trt.ref_id, def); - } - } + self.resolve_trait_reference(*trt, visitor, TraitDerivation); } for (*methods).iter().advance |method| { @@ -3821,7 +3812,7 @@ impl Resolver { visitor: ResolveVisitor) { match *type_parameter_bound { TraitTyParamBound(tref) => { - self.resolve_trait_reference(tref, visitor) + self.resolve_trait_reference(tref, visitor, TraitBoundingTypeParameter) } RegionTyParamBound => {} } @@ -3829,14 +3820,23 @@ impl Resolver { pub fn resolve_trait_reference(@mut self, trait_reference: &trait_ref, - visitor: ResolveVisitor) { + visitor: ResolveVisitor, + reference_type: TraitReferenceType) { match self.resolve_path(trait_reference.path, TypeNS, true, visitor) { None => { - let idents = self.idents_to_str(trait_reference.path.idents); - self.session.span_err(trait_reference.path.span, - fmt!("attempt to implement an unknown trait `%s`", idents)); + let path_str = self.idents_to_str(trait_reference.path.idents); + + let usage_str = match reference_type { + TraitBoundingTypeParameter => "bound type parameter to", + TraitImplementation => "implement", + TraitDerivation => "derive" + }; + + let msg = fmt!("attempt to %s a nonexistent trait `%s`", usage_str, path_str); + self.session.span_err(trait_reference.path.span, msg); } Some(def) => { + debug!("(resolving trait) found trait def: %?", def); self.record_def(trait_reference.ref_id, def); } } @@ -3930,7 +3930,7 @@ impl Resolver { let original_trait_refs; match opt_trait_reference { Some(trait_reference) => { - self.resolve_trait_reference(trait_reference, visitor); + self.resolve_trait_reference(trait_reference, visitor, TraitImplementation); // Record the current set of trait references. let mut new_trait_refs = ~[]; diff --git a/src/test/compile-fail/resolve-unknown-trait.rs b/src/test/compile-fail/resolve-unknown-trait.rs new file mode 100644 index 000000000000..be3b381663a7 --- /dev/null +++ b/src/test/compile-fail/resolve-unknown-trait.rs @@ -0,0 +1,20 @@ +// Copyright 2013 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + + +trait NewTrait : SomeNonExistentTrait {} +//~^ ERROR attempt to derive a nonexistent trait `SomeNonExistentTrait` + +impl SomeNonExistentTrait for int {} +//~^ ERROR attempt to implement a nonexistent trait `SomeNonExistentTrait` + +fn f() {} +//~^ ERROR attempt to bound type parameter to a nonexistent trait `SomeNonExistentTrait` + From 908a22b62697fcb6c943527492158729dc762f10 Mon Sep 17 00:00:00 2001 From: Gareth Smith Date: Wed, 3 Jul 2013 23:43:03 +0100 Subject: [PATCH 34/93] Address @catamorphism's error message grammar nit. --- src/librustc/middle/resolve.rs | 2 +- src/test/compile-fail/resolve-unknown-trait.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 6ddac371e0c6..dc55dcad99d1 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -3827,7 +3827,7 @@ impl Resolver { let path_str = self.idents_to_str(trait_reference.path.idents); let usage_str = match reference_type { - TraitBoundingTypeParameter => "bound type parameter to", + TraitBoundingTypeParameter => "bound type parameter with", TraitImplementation => "implement", TraitDerivation => "derive" }; diff --git a/src/test/compile-fail/resolve-unknown-trait.rs b/src/test/compile-fail/resolve-unknown-trait.rs index be3b381663a7..699a30ad4ebd 100644 --- a/src/test/compile-fail/resolve-unknown-trait.rs +++ b/src/test/compile-fail/resolve-unknown-trait.rs @@ -16,5 +16,5 @@ impl SomeNonExistentTrait for int {} //~^ ERROR attempt to implement a nonexistent trait `SomeNonExistentTrait` fn f() {} -//~^ ERROR attempt to bound type parameter to a nonexistent trait `SomeNonExistentTrait` +//~^ ERROR attempt to bound type parameter with a nonexistent trait `SomeNonExistentTrait` From f80d6dc4c1b9da9d4181742efe1a2206c7d6f5c5 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Fri, 28 Jun 2013 11:15:34 -0700 Subject: [PATCH 35/93] rustc: improve -Z trans-stats to report per-fn LLVM instruction counts and translation timing --- src/librustc/middle/trans/base.rs | 65 +++++++++++++++++++++++----- src/librustc/middle/trans/build.rs | 3 ++ src/librustc/middle/trans/common.rs | 4 +- src/librustc/middle/trans/context.rs | 10 ++--- src/librustc/middle/trans/glue.rs | 12 ++--- 5 files changed, 66 insertions(+), 28 deletions(-) diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index d598a6fbcf91..0ea7c7296243 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -72,6 +72,7 @@ use std::uint; use std::vec; use std::local_data; use extra::time; +use extra::sort; use syntax::ast::ident; use syntax::ast_map::{path, path_elt_to_str, path_name}; use syntax::ast_util::{local_def, path_to_ident}; @@ -141,6 +142,48 @@ fn fcx_has_nonzero_span(fcx: fn_ctxt) -> bool { } } +struct StatRecorder<'self> { + ccx: @mut CrateContext, + name: &'self str, + start: u64, + istart: uint, +} + +impl<'self> StatRecorder<'self> { + pub fn new(ccx: @mut CrateContext, + name: &'self str) -> StatRecorder<'self> { + let start = if ccx.sess.trans_stats() { + time::precise_time_ns() + } else { + 0 + }; + let istart = ccx.stats.n_llvm_insns; + StatRecorder { + ccx: ccx, + name: name, + start: start, + istart: istart, + } + } +} + +#[unsafe_destructor] +impl<'self> Drop for StatRecorder<'self> { + pub fn drop(&self) { + if self.ccx.sess.trans_stats() { + let end = time::precise_time_ns(); + let elapsed = ((end - self.start) / 1_000_000) as uint; + let iend = self.ccx.stats.n_llvm_insns; + self.ccx.stats.fn_stats.push((self.name.to_owned(), + elapsed, + iend - self.istart)); + self.ccx.stats.n_fns += 1; + // Reset LLVM insn count to avoid compound costs. + self.ccx.stats.n_llvm_insns = self.istart; + } + } +} + pub fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv, ty: Type) -> ValueRef { let llfn: ValueRef = do name.as_c_str |buf| { unsafe { @@ -1866,18 +1909,16 @@ pub fn trans_fn(ccx: @mut CrateContext, param_substs: Option<@param_substs>, id: ast::node_id, attrs: &[ast::attribute]) { - let do_time = ccx.sess.trans_stats(); - let start = if do_time { time::get_time() } - else { time::Timespec::new(0, 0) }; + + let the_path_str = path_str(ccx.sess, path); + let _s = StatRecorder::new(ccx, the_path_str); debug!("trans_fn(self_arg=%?, param_substs=%s)", self_arg, param_substs.repr(ccx.tcx)); let _icx = push_ctxt("trans_fn"); - ccx.stats.n_fns += 1; - let the_path_str = path_str(ccx.sess, path); let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx, id)); trans_closure(ccx, - path, + copy path, decl, body, llfndecl, @@ -1893,10 +1934,6 @@ pub fn trans_fn(ccx: @mut CrateContext, } }, |_bcx| { }); - if do_time { - let end = time::get_time(); - ccx.log_fn_time(the_path_str, start, end); - } } pub fn trans_enum_variant(ccx: @mut CrateContext, @@ -2961,8 +2998,14 @@ pub fn trans_crate(sess: session::Session, io::println(fmt!("n_monos: %u", ccx.stats.n_monos)); io::println(fmt!("n_inlines: %u", ccx.stats.n_inlines)); io::println(fmt!("n_closures: %u", ccx.stats.n_closures)); + io::println("fn stats:"); + do sort::quick_sort(ccx.stats.fn_stats) |&(_, _, insns_a), &(_, _, insns_b)| { + insns_a > insns_b + } + for ccx.stats.fn_stats.iter().advance |&(name, ms, insns)| { + io::println(fmt!("%u insns, %u ms, %s", insns, ms, name)); + } } - if ccx.sess.count_llvm_insns() { for ccx.stats.llvm_insns.iter().advance |(&k, &v)| { io::println(fmt!("%-7u %s", v, k)); diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index 811138c6dbdd..b62b73423e9b 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -46,6 +46,9 @@ pub fn B(cx: block) -> BuilderRef { } pub fn count_insn(cx: block, category: &str) { + if cx.ccx().sess.trans_stats() { + cx.ccx().stats.n_llvm_insns += 1; + } do base::with_insn_ctxt |v| { let h = &mut cx.ccx().stats.llvm_insns; diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 865fb26b9455..e4537332e561 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -96,8 +96,10 @@ pub struct Stats { n_monos: uint, n_inlines: uint, n_closures: uint, + n_llvm_insns: uint, + llvm_insn_ctxt: ~[~str], llvm_insns: HashMap<~str, uint>, - fn_times: ~[(~str, int)] // (ident, time) + fn_stats: ~[(~str, uint, uint)] // (ident, time-in-ms, llvm-instructions) } pub struct BuilderRef_res { diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index c2a32ae041e4..ebaa31794428 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -210,8 +210,10 @@ impl CrateContext { n_monos: 0u, n_inlines: 0u, n_closures: 0u, + n_llvm_insns: 0u, + llvm_insn_ctxt: ~[], llvm_insns: HashMap::new(), - fn_times: ~[] + fn_stats: ~[] }, upcalls: upcall::declare_upcalls(targ_cfg, llmod), tydesc_type: tydesc_type, @@ -226,12 +228,6 @@ impl CrateContext { } } } - - pub fn log_fn_time(&mut self, name: ~str, start: time::Timespec, end: time::Timespec) { - let elapsed = 1000 * ((end.sec - start.sec) as int) + - ((end.nsec as int) - (start.nsec as int)) / 1000000; - self.stats.fn_times.push((name, elapsed)); - } } #[unsafe_destructor] diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 68cf66789bfd..84a91cf16150 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -738,15 +738,9 @@ pub fn make_generic_glue(ccx: @mut CrateContext, name: &str) -> ValueRef { let _icx = push_ctxt("make_generic_glue"); - if !ccx.sess.trans_stats() { - return make_generic_glue_inner(ccx, t, llfn, helper); - } - - let start = time::get_time(); - let llval = make_generic_glue_inner(ccx, t, llfn, helper); - let end = time::get_time(); - ccx.log_fn_time(fmt!("glue %s %s", name, ty_to_short_str(ccx.tcx, t)), start, end); - return llval; + let glue_name = fmt!("glue %s %s", name, ty_to_short_str(ccx.tcx, t)); + let _s = StatRecorder::new(ccx, glue_name); + make_generic_glue_inner(ccx, t, llfn, helper) } pub fn emit_tydescs(ccx: &mut CrateContext) { From 5a8a30f45bed02a33b2e0e11f0d07cda2f569533 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 30 Jun 2013 18:08:22 -0400 Subject: [PATCH 36/93] Added functionality to Base64 package The Base64 package previously had extremely basic functionality. It only suported the standard encoding character set, didn't support line breaks and always padded output. This commit makes it significantly more powerful. The FromBase64 impl now supports all of the standard variants of Base64. It ignores newlines,interprets '-' and '_' as well as '+' and '/' and doesn't require padding. It isn't incredibly pedantic and will successfully parse strings that are not strictly valid, but I don't think the extra complexity required to make it accept _only_ valid strings is worth it. The ToBase64 trait has been modified such that to_base64 now takes a base64::Config struct which contains the output format configuration. This currently includes the selection of character set (standard or url safe), whether or not to pad and an optional line break width. The package comes with three static Config structs for the RFC 4648 standard, RFC 4648 url safe and RFC 2045 MIME formats. The other option for configuring ToBase64 output would be to have one method with the configuration flags passed and other traits with default impls for the common cases, but I think that's a little messier. --- src/libextra/base64.rs | 335 ++++++++++++++++++++++++++--------------- 1 file changed, 212 insertions(+), 123 deletions(-) diff --git a/src/libextra/base64.rs b/src/libextra/base64.rs index a53a22ee831d..8a14ed8cc98d 100644 --- a/src/libextra/base64.rs +++ b/src/libextra/base64.rs @@ -10,17 +10,30 @@ //! Base64 binary-to-text encoding - -use std::vec; - -/// A trait for converting a value to base64 encoding. -pub trait ToBase64 { - /// Converts the value of `self` to a base64 value, returning the owned - /// string - fn to_base64(&self) -> ~str; +/// Contains configuration parameters for to_base64 +pub struct Config { + /// True to use the url-safe encoding format ('-' and '_'), false to use + /// the standard encoding format ('+' and '/') + pub url_safe: bool, + /// True to pad output with '=' characters + pub pad: bool, + /// Some(len) to wrap lines at len, None to disable line wrapping + pub line_length: Option } -static CHARS: [char, ..64] = [ +/// Configuration for RFC 4648 standard base64 encoding +pub static standard: Config = + Config {url_safe: false, pad: true, line_length: None}; + +/// Configuration for RFC 4648 base64url encoding +pub static url_safe: Config = + Config {url_safe: true, pad: false, line_length: None}; + +/// Configuration for RFC 2045 MIME base64 encoding +pub static mime: Config = + Config {url_safe: false, pad: true, line_length: Some(76)}; + +static STANDARD_CHARS: [char, ..64] = [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', @@ -28,6 +41,21 @@ static CHARS: [char, ..64] = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' ]; +static URLSAFE_CHARS: [char, ..64] = [ + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_' +]; + +/// A trait for converting a value to base64 encoding. +pub trait ToBase64 { + /// Converts the value of `self` to a base64 value following the specified + /// format configuration, returning the owned string. + fn to_base64(&self, config: Config) -> ~str; +} + impl<'self> ToBase64 for &'self [u8] { /** * Turn a vector of `u8` bytes into a base64 string. @@ -35,56 +63,81 @@ impl<'self> ToBase64 for &'self [u8] { * # Example * * ~~~ {.rust} - * extern mod extra; - * use extra::base64::ToBase64; + * use std::base64::{ToBase64, standard}; * * fn main () { - * let str = [52,32].to_base64(); + * let str = [52,32].to_base64(standard); * println(fmt!("%s", str)); * } * ~~~ */ - fn to_base64(&self) -> ~str { + fn to_base64(&self, config: Config) -> ~str { + let chars = match config.url_safe { + true => URLSAFE_CHARS, + false => STANDARD_CHARS + }; + let mut s = ~""; + let mut i = 0; + let mut cur_length = 0; let len = self.len(); - s.reserve(((len + 3u) / 4u) * 3u); + while i < len - (len % 3) { + match config.line_length { + Some(line_length) => + if cur_length >= line_length { + s.push_str("\r\n"); + cur_length = 0; + }, + None => () + } - let mut i = 0u; - - while i < len - (len % 3u) { - let n = (self[i] as uint) << 16u | - (self[i + 1u] as uint) << 8u | - (self[i + 2u] as uint); + let n = (self[i] as u32) << 16 | + (self[i + 1] as u32) << 8 | + (self[i + 2] as u32); // This 24-bit number gets separated into four 6-bit numbers. - s.push_char(CHARS[(n >> 18u) & 63u]); - s.push_char(CHARS[(n >> 12u) & 63u]); - s.push_char(CHARS[(n >> 6u) & 63u]); - s.push_char(CHARS[n & 63u]); + s.push_char(chars[(n >> 18) & 63]); + s.push_char(chars[(n >> 12) & 63]); + s.push_char(chars[(n >> 6 ) & 63]); + s.push_char(chars[n & 63]); - i += 3u; + cur_length += 4; + i += 3; + } + + if len % 3 != 0 { + match config.line_length { + Some(line_length) => + if cur_length >= line_length { + s.push_str("\r\n"); + }, + None => () + } } // Heh, would be cool if we knew this was exhaustive // (the dream of bounded integer types) match len % 3 { - 0 => (), - 1 => { - let n = (self[i] as uint) << 16u; - s.push_char(CHARS[(n >> 18u) & 63u]); - s.push_char(CHARS[(n >> 12u) & 63u]); - s.push_char('='); - s.push_char('='); - } - 2 => { - let n = (self[i] as uint) << 16u | - (self[i + 1u] as uint) << 8u; - s.push_char(CHARS[(n >> 18u) & 63u]); - s.push_char(CHARS[(n >> 12u) & 63u]); - s.push_char(CHARS[(n >> 6u) & 63u]); - s.push_char('='); - } - _ => fail!("Algebra is broken, please alert the math police") + 0 => (), + 1 => { + let n = (self[i] as u32) << 16; + s.push_char(chars[(n >> 18) & 63]); + s.push_char(chars[(n >> 12) & 63]); + if config.pad { + s.push_str("=="); + } + } + 2 => { + let n = (self[i] as u32) << 16 | + (self[i + 1u] as u32) << 8; + s.push_char(chars[(n >> 18) & 63]); + s.push_char(chars[(n >> 12) & 63]); + s.push_char(chars[(n >> 6 ) & 63]); + if config.pad { + s.push_char('='); + } + } + _ => fail!("Algebra is broken, please alert the math police") } s } @@ -98,23 +151,24 @@ impl<'self> ToBase64 for &'self str { * # Example * * ~~~ {.rust} - * extern mod extra; - * use extra::base64::ToBase64; + * use std::base64::{ToBase64, standard}; * * fn main () { - * let str = "Hello, World".to_base64(); + * let str = "Hello, World".to_base64(standard); * println(fmt!("%s",str)); * } * ~~~ * */ - fn to_base64(&self) -> ~str { - self.as_bytes().to_base64() + fn to_base64(&self, config: Config) -> ~str { + self.as_bytes().to_base64(config) } } -#[allow(missing_doc)] +/// A trait for converting from base64 encoded values. pub trait FromBase64 { + /// Converts the value of `self`, interpreted as base64 encoded data, into + /// an owned vector of bytes, returning the vector. fn from_base64(&self) -> ~[u8]; } @@ -126,12 +180,10 @@ impl<'self> FromBase64 for &'self [u8] { * # Example * * ~~~ {.rust} - * extern mod extra; - * use extra::base64::ToBase64; - * use extra::base64::FromBase64; + * use std::base64::{ToBase64, FromBase64, standard}; * * fn main () { - * let str = [52,32].to_base64(); + * let str = [52,32].to_base64(standard); * println(fmt!("%s", str)); * let bytes = str.from_base64(); * println(fmt!("%?",bytes)); @@ -139,56 +191,52 @@ impl<'self> FromBase64 for &'self [u8] { * ~~~ */ fn from_base64(&self) -> ~[u8] { - if self.len() % 4u != 0u { fail!("invalid base64 length"); } + let mut r = ~[]; + let mut buf: u32 = 0; + let mut modulus = 0; - let len = self.len(); - let mut padding = 0u; + let mut it = self.iter(); + for it.advance |&byte| { + let ch = byte as char; + let val = byte as u32; - if len != 0u { - if self[len - 1u] == '=' as u8 { padding += 1u; } - if self[len - 2u] == '=' as u8 { padding += 1u; } + match ch { + 'A'..'Z' => buf |= val - 0x41, + 'a'..'z' => buf |= val - 0x47, + '0'..'9' => buf |= val + 0x04, + '+'|'-' => buf |= 0x3E, + '/'|'_' => buf |= 0x3F, + '\r'|'\n' => loop, + '=' => break, + _ => fail!("Invalid Base64 character") + } + + buf <<= 6; + modulus += 1; + if modulus == 4 { + modulus = 0; + r.push((buf >> 22) as u8); + r.push((buf >> 14) as u8); + r.push((buf >> 6 ) as u8); + } } - let mut r = vec::with_capacity((len / 4u) * 3u - padding); - - let mut i = 0u; - while i < len { - let mut n = 0u; - - for 4u.times { - let ch = self[i] as char; - n <<= 6u; - - match ch { - 'A'..'Z' => n |= (ch as uint) - 0x41, - 'a'..'z' => n |= (ch as uint) - 0x47, - '0'..'9' => n |= (ch as uint) + 0x04, - '+' => n |= 0x3E, - '/' => n |= 0x3F, - '=' => { - match len - i { - 1u => { - r.push(((n >> 16u) & 0xFFu) as u8); - r.push(((n >> 8u ) & 0xFFu) as u8); - return copy r; - } - 2u => { - r.push(((n >> 10u) & 0xFFu) as u8); - return copy r; - } - _ => fail!("invalid base64 padding") - } - } - _ => fail!("invalid base64 character") - } - - i += 1u; - }; - - r.push(((n >> 16u) & 0xFFu) as u8); - r.push(((n >> 8u ) & 0xFFu) as u8); - r.push(((n ) & 0xFFu) as u8); + if !it.all(|&byte| {byte as char == '='}) { + fail!("Invalid Base64 character"); } + + match modulus { + 2 => { + r.push((buf >> 10) as u8); + } + 3 => { + r.push((buf >> 16) as u8); + r.push((buf >> 8 ) as u8); + } + 0 => (), + _ => fail!("Invalid Base64 length") + } + r } } @@ -199,20 +247,19 @@ impl<'self> FromBase64 for &'self str { * to the byte values it encodes. * * You can use the `from_bytes` function in `std::str` - * to turn a `[u8]` into a string with characters corresponding to those values. + * to turn a `[u8]` into a string with characters corresponding to those + * values. * * # Example * * This converts a string literal to base64 and back. * * ~~~ {.rust} - * extern mod extra; - * use extra::base64::ToBase64; - * use extra::base64::FromBase64; + * use std::base64::{ToBase64, FromBase64, standard}; * use std::str; * * fn main () { - * let hello_str = "Hello, World".to_base64(); + * let hello_str = "Hello, World".to_base64(standard); * println(fmt!("%s",hello_str)); * let bytes = hello_str.from_base64(); * println(fmt!("%?",bytes)); @@ -226,27 +273,69 @@ impl<'self> FromBase64 for &'self str { } } -#[cfg(test)] -mod tests { - #[test] - fn test_to_base64() { - assert_eq!("".to_base64(), ~""); - assert_eq!("f".to_base64(), ~"Zg=="); - assert_eq!("fo".to_base64(), ~"Zm8="); - assert_eq!("foo".to_base64(), ~"Zm9v"); - assert_eq!("foob".to_base64(), ~"Zm9vYg=="); - assert_eq!("fooba".to_base64(), ~"Zm9vYmE="); - assert_eq!("foobar".to_base64(), ~"Zm9vYmFy"); - } +#[test] +fn test_to_base64_basic() { + assert_eq!("".to_base64(standard), ~""); + assert_eq!("f".to_base64(standard), ~"Zg=="); + assert_eq!("fo".to_base64(standard), ~"Zm8="); + assert_eq!("foo".to_base64(standard), ~"Zm9v"); + assert_eq!("foob".to_base64(standard), ~"Zm9vYg=="); + assert_eq!("fooba".to_base64(standard), ~"Zm9vYmE="); + assert_eq!("foobar".to_base64(standard), ~"Zm9vYmFy"); +} - #[test] - fn test_from_base64() { - assert_eq!("".from_base64(), "".as_bytes().to_owned()); - assert_eq!("Zg==".from_base64(), "f".as_bytes().to_owned()); - assert_eq!("Zm8=".from_base64(), "fo".as_bytes().to_owned()); - assert_eq!("Zm9v".from_base64(), "foo".as_bytes().to_owned()); - assert_eq!("Zm9vYg==".from_base64(), "foob".as_bytes().to_owned()); - assert_eq!("Zm9vYmE=".from_base64(), "fooba".as_bytes().to_owned()); - assert_eq!("Zm9vYmFy".from_base64(), "foobar".as_bytes().to_owned()); +#[test] +fn test_to_base64_line_break() { + assert!(![0u8, 1000].to_base64(Config {line_length: None, ..standard}) + .contains("\r\n")); + assert_eq!("foobar".to_base64(Config {line_length: Some(4), ..standard}), + ~"Zm9v\r\nYmFy"); +} + +#[test] +fn test_to_base64_padding() { + assert_eq!("f".to_base64(Config {pad: false, ..standard}), ~"Zg"); + assert_eq!("fo".to_base64(Config {pad: false, ..standard}), ~"Zm8"); +} + +#[test] +fn test_to_base64_url_safe() { + assert_eq!([251, 255].to_base64(url_safe), ~"-_8"); + assert_eq!([251, 255].to_base64(standard), ~"+/8="); +} + +#[test] +fn test_from_base64_basic() { + assert_eq!("".from_base64(), "".as_bytes().to_owned()); + assert_eq!("Zg==".from_base64(), "f".as_bytes().to_owned()); + assert_eq!("Zm8=".from_base64(), "fo".as_bytes().to_owned()); + assert_eq!("Zm9v".from_base64(), "foo".as_bytes().to_owned()); + assert_eq!("Zm9vYg==".from_base64(), "foob".as_bytes().to_owned()); + assert_eq!("Zm9vYmE=".from_base64(), "fooba".as_bytes().to_owned()); + assert_eq!("Zm9vYmFy".from_base64(), "foobar".as_bytes().to_owned()); +} + +#[test] +fn test_from_base64_newlines() { + assert_eq!("Zm9v\r\nYmFy".from_base64(), "foobar".as_bytes().to_owned()); +} + +#[test] +fn test_from_base64_urlsafe() { + assert_eq!("-_8".from_base64(), "+/8=".from_base64()); +} + +#[test] +fn test_base64_random() { + use std::rand::random; + use std::vec; + + for 1000.times { + let v: ~[u8] = do vec::build |push| { + for 100.times { + push(random()); + } + }; + assert_eq!(v.to_base64(standard).from_base64(), v); } } From 1482cf5ded3998fa8edb01999287d22594f1e4bb Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Mon, 1 Jul 2013 00:08:49 -0400 Subject: [PATCH 37/93] Base64 API changes There's now an enum to pick the character set instead of a url_safe bool. from_base64 now returns a Result<~[u8], ~str> and returns an Err instead of killing the task when it is called on invalid input. Fixed documentation examples. --- src/libextra/base64.rs | 91 ++++++++++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 34 deletions(-) diff --git a/src/libextra/base64.rs b/src/libextra/base64.rs index 8a14ed8cc98d..08a05d1d8a88 100644 --- a/src/libextra/base64.rs +++ b/src/libextra/base64.rs @@ -10,28 +10,35 @@ //! Base64 binary-to-text encoding +/// Available encoding character sets +pub enum CharacterSet { + /// The standard character set (uses '+' and '/') + Standard, + /// The URL safe character set (uses '-' and '_') + UrlSafe +} + /// Contains configuration parameters for to_base64 pub struct Config { - /// True to use the url-safe encoding format ('-' and '_'), false to use - /// the standard encoding format ('+' and '/') - pub url_safe: bool, + /// Character set to use + char_set: CharacterSet, /// True to pad output with '=' characters - pub pad: bool, + pad: bool, /// Some(len) to wrap lines at len, None to disable line wrapping - pub line_length: Option + line_length: Option } /// Configuration for RFC 4648 standard base64 encoding pub static standard: Config = - Config {url_safe: false, pad: true, line_length: None}; + Config {char_set: Standard, pad: true, line_length: None}; /// Configuration for RFC 4648 base64url encoding pub static url_safe: Config = - Config {url_safe: true, pad: false, line_length: None}; + Config {char_set: UrlSafe, pad: false, line_length: None}; /// Configuration for RFC 2045 MIME base64 encoding pub static mime: Config = - Config {url_safe: false, pad: true, line_length: Some(76)}; + Config {char_set: Standard, pad: true, line_length: Some(76)}; static STANDARD_CHARS: [char, ..64] = [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', @@ -63,7 +70,8 @@ impl<'self> ToBase64 for &'self [u8] { * # Example * * ~~~ {.rust} - * use std::base64::{ToBase64, standard}; + * extern mod extra; + * use extra::base64::{ToBase64, standard}; * * fn main () { * let str = [52,32].to_base64(standard); @@ -72,9 +80,9 @@ impl<'self> ToBase64 for &'self [u8] { * ~~~ */ fn to_base64(&self, config: Config) -> ~str { - let chars = match config.url_safe { - true => URLSAFE_CHARS, - false => STANDARD_CHARS + let chars = match config.char_set { + Standard => STANDARD_CHARS, + UrlSafe => URLSAFE_CHARS }; let mut s = ~""; @@ -151,7 +159,8 @@ impl<'self> ToBase64 for &'self str { * # Example * * ~~~ {.rust} - * use std::base64::{ToBase64, standard}; + * extern mod extra; + * use extra::base64::{ToBase64, standard}; * * fn main () { * let str = "Hello, World".to_base64(standard); @@ -169,7 +178,7 @@ impl<'self> ToBase64 for &'self str { pub trait FromBase64 { /// Converts the value of `self`, interpreted as base64 encoded data, into /// an owned vector of bytes, returning the vector. - fn from_base64(&self) -> ~[u8]; + fn from_base64(&self) -> Result<~[u8], ~str>; } impl<'self> FromBase64 for &'self [u8] { @@ -180,7 +189,8 @@ impl<'self> FromBase64 for &'self [u8] { * # Example * * ~~~ {.rust} - * use std::base64::{ToBase64, FromBase64, standard}; + * extern mod extra; + * use extra::base64::{ToBase64, FromBase64, standard}; * * fn main () { * let str = [52,32].to_base64(standard); @@ -190,7 +200,7 @@ impl<'self> FromBase64 for &'self [u8] { * } * ~~~ */ - fn from_base64(&self) -> ~[u8] { + fn from_base64(&self) -> Result<~[u8], ~str> { let mut r = ~[]; let mut buf: u32 = 0; let mut modulus = 0; @@ -208,7 +218,7 @@ impl<'self> FromBase64 for &'self [u8] { '/'|'_' => buf |= 0x3F, '\r'|'\n' => loop, '=' => break, - _ => fail!("Invalid Base64 character") + _ => return Err(~"Invalid Base64 character") } buf <<= 6; @@ -222,7 +232,7 @@ impl<'self> FromBase64 for &'self [u8] { } if !it.all(|&byte| {byte as char == '='}) { - fail!("Invalid Base64 character"); + return Err(~"Invalid Base64 character"); } match modulus { @@ -234,10 +244,10 @@ impl<'self> FromBase64 for &'self [u8] { r.push((buf >> 8 ) as u8); } 0 => (), - _ => fail!("Invalid Base64 length") + _ => return Err(~"Invalid Base64 length") } - r + Ok(r) } } @@ -255,7 +265,8 @@ impl<'self> FromBase64 for &'self str { * This converts a string literal to base64 and back. * * ~~~ {.rust} - * use std::base64::{ToBase64, FromBase64, standard}; + * extern mod extra; + * use extra::base64::{ToBase64, FromBase64, standard}; * use std::str; * * fn main () { @@ -268,7 +279,7 @@ impl<'self> FromBase64 for &'self str { * } * ~~~ */ - fn from_base64(&self) -> ~[u8] { + fn from_base64(&self) -> Result<~[u8], ~str> { self.as_bytes().from_base64() } } @@ -306,36 +317,48 @@ fn test_to_base64_url_safe() { #[test] fn test_from_base64_basic() { - assert_eq!("".from_base64(), "".as_bytes().to_owned()); - assert_eq!("Zg==".from_base64(), "f".as_bytes().to_owned()); - assert_eq!("Zm8=".from_base64(), "fo".as_bytes().to_owned()); - assert_eq!("Zm9v".from_base64(), "foo".as_bytes().to_owned()); - assert_eq!("Zm9vYg==".from_base64(), "foob".as_bytes().to_owned()); - assert_eq!("Zm9vYmE=".from_base64(), "fooba".as_bytes().to_owned()); - assert_eq!("Zm9vYmFy".from_base64(), "foobar".as_bytes().to_owned()); + assert_eq!("".from_base64().get(), "".as_bytes().to_owned()); + assert_eq!("Zg==".from_base64().get(), "f".as_bytes().to_owned()); + assert_eq!("Zm8=".from_base64().get(), "fo".as_bytes().to_owned()); + assert_eq!("Zm9v".from_base64().get(), "foo".as_bytes().to_owned()); + assert_eq!("Zm9vYg==".from_base64().get(), "foob".as_bytes().to_owned()); + assert_eq!("Zm9vYmE=".from_base64().get(), "fooba".as_bytes().to_owned()); + assert_eq!("Zm9vYmFy".from_base64().get(), "foobar".as_bytes().to_owned()); } #[test] fn test_from_base64_newlines() { - assert_eq!("Zm9v\r\nYmFy".from_base64(), "foobar".as_bytes().to_owned()); + assert_eq!("Zm9v\r\nYmFy".from_base64().get(), + "foobar".as_bytes().to_owned()); } #[test] fn test_from_base64_urlsafe() { - assert_eq!("-_8".from_base64(), "+/8=".from_base64()); + assert_eq!("-_8".from_base64().get(), "+/8=".from_base64().get()); +} + +#[test] +fn test_from_base64_invalid_char() { + assert!("Zm$=".from_base64().is_err()) + assert!("Zg==$".from_base64().is_err()); +} + +#[test] +fn test_from_base64_invalid_padding() { + assert!("Z===".from_base64().is_err()); } #[test] fn test_base64_random() { - use std::rand::random; + use std::rand::{task_rng, random, RngUtil}; use std::vec; for 1000.times { let v: ~[u8] = do vec::build |push| { - for 100.times { + for task_rng().gen_uint_range(1, 100).times { push(random()); } }; - assert_eq!(v.to_base64(standard).from_base64(), v); + assert_eq!(v.to_base64(standard).from_base64().get(), v); } } From 23da3802917f62308342b57649273943e40076d2 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Wed, 3 Jul 2013 23:23:29 -0400 Subject: [PATCH 38/93] force LLVM clean --- src/rustllvm/llvm-auto-clean-trigger | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rustllvm/llvm-auto-clean-trigger b/src/rustllvm/llvm-auto-clean-trigger index fbd687778ae7..9b8f0e3a4621 100644 --- a/src/rustllvm/llvm-auto-clean-trigger +++ b/src/rustllvm/llvm-auto-clean-trigger @@ -1,4 +1,4 @@ # If this file is modified, then llvm will be forcibly cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. -6-29-2013 +2013-07-03 From e9988c1e2d9ec0a1442f8591804c471ee11e1924 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Wed, 3 Jul 2013 23:33:55 -0400 Subject: [PATCH 39/93] Upper-cased exported statics --- src/libextra/base64.rs | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/libextra/base64.rs b/src/libextra/base64.rs index 08a05d1d8a88..3c1fc72e9578 100644 --- a/src/libextra/base64.rs +++ b/src/libextra/base64.rs @@ -29,15 +29,15 @@ pub struct Config { } /// Configuration for RFC 4648 standard base64 encoding -pub static standard: Config = +pub static STANDARD: Config = Config {char_set: Standard, pad: true, line_length: None}; /// Configuration for RFC 4648 base64url encoding -pub static url_safe: Config = +pub static URL_SAFE: Config = Config {char_set: UrlSafe, pad: false, line_length: None}; /// Configuration for RFC 2045 MIME base64 encoding -pub static mime: Config = +pub static MIME: Config = Config {char_set: Standard, pad: true, line_length: Some(76)}; static STANDARD_CHARS: [char, ..64] = [ @@ -286,33 +286,33 @@ impl<'self> FromBase64 for &'self str { #[test] fn test_to_base64_basic() { - assert_eq!("".to_base64(standard), ~""); - assert_eq!("f".to_base64(standard), ~"Zg=="); - assert_eq!("fo".to_base64(standard), ~"Zm8="); - assert_eq!("foo".to_base64(standard), ~"Zm9v"); - assert_eq!("foob".to_base64(standard), ~"Zm9vYg=="); - assert_eq!("fooba".to_base64(standard), ~"Zm9vYmE="); - assert_eq!("foobar".to_base64(standard), ~"Zm9vYmFy"); + assert_eq!("".to_base64(STANDARD), ~""); + assert_eq!("f".to_base64(STANDARD), ~"Zg=="); + assert_eq!("fo".to_base64(STANDARD), ~"Zm8="); + assert_eq!("foo".to_base64(STANDARD), ~"Zm9v"); + assert_eq!("foob".to_base64(STANDARD), ~"Zm9vYg=="); + assert_eq!("fooba".to_base64(STANDARD), ~"Zm9vYmE="); + assert_eq!("foobar".to_base64(STANDARD), ~"Zm9vYmFy"); } #[test] fn test_to_base64_line_break() { - assert!(![0u8, 1000].to_base64(Config {line_length: None, ..standard}) + assert!(![0u8, 1000].to_base64(Config {line_length: None, ..STANDARD}) .contains("\r\n")); - assert_eq!("foobar".to_base64(Config {line_length: Some(4), ..standard}), + assert_eq!("foobar".to_base64(Config {line_length: Some(4), ..STANDARD}), ~"Zm9v\r\nYmFy"); } #[test] fn test_to_base64_padding() { - assert_eq!("f".to_base64(Config {pad: false, ..standard}), ~"Zg"); - assert_eq!("fo".to_base64(Config {pad: false, ..standard}), ~"Zm8"); + assert_eq!("f".to_base64(Config {pad: false, ..STANDARD}), ~"Zg"); + assert_eq!("fo".to_base64(Config {pad: false, ..STANDARD}), ~"Zm8"); } #[test] fn test_to_base64_url_safe() { - assert_eq!([251, 255].to_base64(url_safe), ~"-_8"); - assert_eq!([251, 255].to_base64(standard), ~"+/8="); + assert_eq!([251, 255].to_base64(URL_SAFE), ~"-_8"); + assert_eq!([251, 255].to_base64(STANDARD), ~"+/8="); } #[test] @@ -359,6 +359,6 @@ fn test_base64_random() { push(random()); } }; - assert_eq!(v.to_base64(standard).from_base64().get(), v); + assert_eq!(v.to_base64(STANDARD).from_base64().get(), v); } } From 5007fb2d4dc5a7bcdacd55e6e8b14f6973c2490c Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Wed, 3 Jul 2013 23:33:59 -0400 Subject: [PATCH 40/93] Add x64 windows to platform.mk and mingw64 header fixes. --- mk/platform.mk | 29 +++++++++++++++++++++++++++-- src/rt/rust_uv.cpp | 3 ++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/mk/platform.mk b/mk/platform.mk index 4bb8de28aefa..61a170c21d51 100644 --- a/mk/platform.mk +++ b/mk/platform.mk @@ -323,9 +323,9 @@ AR_i686-pc-mingw32=$(AR) CFG_LIB_NAME_i686-pc-mingw32=$(1).dll CFG_LIB_GLOB_i686-pc-mingw32=$(1)-*.dll CFG_LIB_DSYM_GLOB_i686-pc-mingw32=$(1)-*.dylib.dSYM -CFG_GCCISH_CFLAGS_i686-pc-mingw32 := -Wall -Werror -g -march=i686 +CFG_GCCISH_CFLAGS_i686-pc-mingw32 := -Wall -Werror -g -m32 -march=i686 -D_WIN32_WINNT=0x0600 CFG_GCCISH_CXXFLAGS_i686-pc-mingw32 := -fno-rtti -CFG_GCCISH_LINK_FLAGS_i686-pc-mingw32 := -shared -fPIC -g +CFG_GCCISH_LINK_FLAGS_i686-pc-mingw32 := -shared -fPIC -g -m32 CFG_GCCISH_DEF_FLAG_i686-pc-mingw32 := CFG_GCCISH_PRE_LIB_FLAGS_i686-pc-mingw32 := CFG_GCCISH_POST_LIB_FLAGS_i686-pc-mingw32 := @@ -367,6 +367,31 @@ CFG_LDPATH_i586-mingw32msvc := CFG_RUN_i586-mingw32msvc= CFG_RUN_TARG_i586-mingw32msvc= +# x86_64-w64-mingw32 configuration +CC_x86_64-w64-mingw32=$(CC) +CXX_x86_64-w64-mingw32=$(CXX) +CPP_x86_64-w64-mingw32=$(CPP) +AR_x86_64-w64-mingw32=$(AR) +CFG_LIB_NAME_x86_64-w64-mingw32=$(1).dll +CFG_LIB_GLOB_x86_64-w64-mingw32=$(1)-*.dll +CFG_LIB_DSYM_GLOB_x86_64-w64-mingw32=$(1)-*.dylib.dSYM +CFG_GCCISH_CFLAGS_x86_64-w64-mingw32 := -Wall -Werror -g -m64 -D_WIN32_WINNT=0x0600 +CFG_GCCISH_CXXFLAGS_x86_64-w64-mingw32 := -fno-rtti +CFG_GCCISH_LINK_FLAGS_x86_64-w64-mingw32 := -shared -fPIC -g -m64 +CFG_GCCISH_DEF_FLAG_x86_64-w64-mingw32 := +CFG_GCCISH_PRE_LIB_FLAGS_x86_64-w64-mingw32 := +CFG_GCCISH_POST_LIB_FLAGS_x86_64-w64-mingw32 := +CFG_DEF_SUFFIX_x86_64-w64-mingw32 := .mingw32.def +CFG_INSTALL_NAME_x86_64-w64-mingw32 = +CFG_LIBUV_LINK_FLAGS_x86_64-w64-mingw32 := -lWs2_32 -lpsapi -liphlpapi +CFG_EXE_SUFFIX_x86_64-w64-mingw32 := .exe +CFG_WINDOWSY_x86_64-w64-mingw32 := 1 +CFG_UNIXY_x86_64-w64-mingw32 := +CFG_PATH_MUNGE_x86_64-w64-mingw32 := +CFG_LDPATH_x86_64-w64-mingw32 :=$(CFG_LDPATH_x86_64-w64-mingw32):$(PATH) +CFG_RUN_x86_64-w64-mingw32=PATH="$(CFG_LDPATH_x86_64-w64-mingw32):$(1)" $(2) +CFG_RUN_TARG_x86_64-w64-mingw32=$(call CFG_RUN_x86_64-w64-mingw32,$(HLIB$(1)_H_$(CFG_BUILD_TRIPLE)),$(2)) + # x86_64-unknown-freebsd configuration CC_x86_64-unknown-freebsd=$(CC) CXX_x86_64-unknown-freebsd=$(CXX) diff --git a/src/rt/rust_uv.cpp b/src/rt/rust_uv.cpp index fefcbbcacf7d..dbd52e088f0f 100644 --- a/src/rt/rust_uv.cpp +++ b/src/rt/rust_uv.cpp @@ -13,10 +13,11 @@ #include #endif +#include "uv.h" + #include "rust_globals.h" #include "rust_task.h" #include "rust_log.h" -#include "uv.h" // extern fn pointers typedef void (*extern_async_op_cb)(uv_loop_t* loop, void* data, From e80dcf700b97d6d9899a291357a21e22d965c9c0 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 3 Jul 2013 23:26:38 -0700 Subject: [PATCH 41/93] Use #[allow(warnings)] in rusti instead of explicitly listing warnings --- src/librusti/program.rs | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/librusti/program.rs b/src/librusti/program.rs index 869b3472422b..e15cc04fa9b7 100644 --- a/src/librusti/program.rs +++ b/src/librusti/program.rs @@ -196,21 +196,7 @@ impl Program { // up front, disable lots of annoying lints, then include all global // state such as items, view items, and extern mods. let mut code = fmt!(" - #[allow(ctypes)]; - #[allow(heap_memory)]; - #[allow(implicit_copies)]; - #[allow(managed_heap_memory)]; - #[allow(non_camel_case_types)]; - #[allow(owned_heap_memory)]; - #[allow(path_statement)]; - #[allow(unrecognized_lint)]; - #[allow(unused_imports)]; - #[allow(while_true)]; - #[allow(unused_variable)]; - #[allow(dead_assignment)]; - #[allow(unused_unsafe)]; - #[allow(unused_mut)]; - #[allow(unreachable_code)]; + #[allow(warnings)]; extern mod extra; %s // extern mods From 8cb1a290a80d1500078a956d434f7c234c9f8e6a Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Thu, 4 Jul 2013 11:56:11 +0200 Subject: [PATCH 42/93] Removed drop from the keyword list in the docs --- doc/rust.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/rust.md b/doc/rust.md index 1db9dac9b582..2ec5e939487b 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -207,7 +207,7 @@ The keywords are the following strings: as break copy -do drop +do else enum extern false fn for if impl From e9ce97cc2a702679c81fa259f6dc5fca07d9cf20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aljaz=CC=8C=20=22g5pw=22=20Srebrnic=CC=8C?= Date: Thu, 4 Jul 2013 16:18:05 +0200 Subject: [PATCH 43/93] Copy the correct libs when using local-rust-root This fixes a segfault when configuring rust to use local-rust-root. The libraries were renamed in the 0.6-0.7 transition, and the script was not copying them all. I also removed the line referencing libcore (now libstd). --- src/etc/local_stage0.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/etc/local_stage0.sh b/src/etc/local_stage0.sh index 8d2fd887e3ff..3b70f9b967fb 100755 --- a/src/etc/local_stage0.sh +++ b/src/etc/local_stage0.sh @@ -43,7 +43,7 @@ fi cp ${PREFIX}/bin/rustc ${TARG_DIR}/stage0/bin/ cp ${PREFIX}/lib/rustc/${TARG_DIR}/${LIBDIR}/* ${TARG_DIR}/stage0/${LIBDIR}/ +cp ${PREFIX}/lib/libextra*${LIB_SUF} ${TARG_DIR}/stage0/${LIBDIR}/ cp ${PREFIX}/lib/librust*${LIB_SUF} ${TARG_DIR}/stage0/${LIBDIR}/ -cp ${PREFIX}/lib/libcore*${LIB_SUF} ${TARG_DIR}/stage0/${LIBDIR}/ cp ${PREFIX}/lib/libstd*${LIB_SUF} ${TARG_DIR}/stage0/${LIBDIR}/ cp ${PREFIX}/lib/libsyntax*${LIB_SUF} ${TARG_DIR}/stage0/${LIBDIR}/ From 3c5cfdf2e7e53967eb330928aaeedfbb8ea1db4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Thu, 4 Jul 2013 19:51:11 +0200 Subject: [PATCH 44/93] libsyntax: fix infinite loop when recursively including modules Fixes #7276 --- src/libsyntax/parse/mod.rs | 4 ++++ src/libsyntax/parse/parser.rs | 21 +++++++++++++++++-- .../compile-fail/circular_modules_hello.rs | 17 +++++++++++++++ .../compile-fail/circular_modules_main.rs | 20 ++++++++++++++++++ 4 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 src/test/compile-fail/circular_modules_hello.rs create mode 100644 src/test/compile-fail/circular_modules_main.rs diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 6dd8d4880e3f..67ae695508bc 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -44,6 +44,8 @@ pub struct ParseSess { cm: @codemap::CodeMap, // better be the same as the one in the reader! next_id: node_id, span_diagnostic: @span_handler, // better be the same as the one in the reader! + /// Used to determine and report recursive mod inclusions + included_mod_stack: ~[Path], } pub fn new_parse_sess(demitter: Option) -> @mut ParseSess { @@ -52,6 +54,7 @@ pub fn new_parse_sess(demitter: Option) -> @mut ParseSess { cm: cm, next_id: 1, span_diagnostic: mk_span_handler(mk_handler(demitter), cm), + included_mod_stack: ~[], } } @@ -62,6 +65,7 @@ pub fn new_parse_sess_special_handler(sh: @span_handler, cm: cm, next_id: 1, span_diagnostic: sh, + included_mod_stack: ~[], } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index cc0baa28e20d..611d58f852d9 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -264,7 +264,6 @@ pub struct Parser { obsolete_set: @mut HashSet, /// Used to determine the path to externally loaded source files mod_path_stack: @mut ~[@str], - } #[unsafe_destructor] @@ -3834,7 +3833,7 @@ impl Parser { (id, item_static(ty, m, e), None) } - // parse a mod { ...} item + // parse a `mod { ... }` or `mod ;` item fn parse_item_mod(&self, outer_attrs: ~[ast::attribute]) -> item_info { let id_span = *self.span; let id = self.parse_ident(); @@ -3907,6 +3906,23 @@ impl Parser { prefix.push_many(path.components) }; let full_path = full_path.normalize(); + + let maybe_i = do self.sess.included_mod_stack.iter().position_ |&p| { p == full_path }; + match maybe_i { + Some(i) => { + let stack = &self.sess.included_mod_stack; + let mut err = ~"circular modules: "; + for stack.slice(i, stack.len()).iter().advance |p| { + err.push_str(p.to_str()); + err.push_str(" -> "); + } + err.push_str(full_path.to_str()); + self.span_fatal(id_sp, err); + } + None => () + } + self.sess.included_mod_stack.push(full_path.clone()); + let p0 = new_sub_parser_from_file(self.sess, copy self.cfg, &full_path, id_sp); @@ -3914,6 +3930,7 @@ impl Parser { let mod_attrs = vec::append(outer_attrs, inner); let first_item_outer_attrs = next; let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs); + self.sess.included_mod_stack.pop(); return (ast::item_mod(m0), mod_attrs); fn cdir_path_opt(default: @str, attrs: ~[ast::attribute]) -> @str { diff --git a/src/test/compile-fail/circular_modules_hello.rs b/src/test/compile-fail/circular_modules_hello.rs new file mode 100644 index 000000000000..261fa489f610 --- /dev/null +++ b/src/test/compile-fail/circular_modules_hello.rs @@ -0,0 +1,17 @@ +// Copyright 2013 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// xfail-test: this is an auxiliary file for circular-modules-main.rs + +mod circular_modules_main; + +pub fn say_hello() { + println(circular_modules_main::hi_str()); +} diff --git a/src/test/compile-fail/circular_modules_main.rs b/src/test/compile-fail/circular_modules_main.rs new file mode 100644 index 000000000000..06b5854f42c8 --- /dev/null +++ b/src/test/compile-fail/circular_modules_main.rs @@ -0,0 +1,20 @@ +// Copyright 2013 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + + +mod circular_modules_hello; //~ERROR: circular modules + +pub fn hi_str() -> ~str { + ~"Hi!" +} + +fn main() { + circular_modules_hello::say_hello(); +} From 8552a7477544b4bbf6ddd39e011a0e514cfd75d6 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 30 Jun 2013 19:36:55 -0700 Subject: [PATCH 45/93] Bring compiletest/rustpkg/driver up to date on std vs core --- mk/tools.mk | 2 +- src/compiletest/common.rs | 2 -- src/compiletest/compiletest.rs | 36 +++++++++++--------------------- src/compiletest/errors.rs | 4 +--- src/compiletest/header.rs | 6 ++---- src/compiletest/procsrv.rs | 8 +++---- src/compiletest/runtest.rs | 10 ++++----- src/compiletest/util.rs | 6 ++---- src/driver/driver.rs | 5 ----- src/librusti/rusti.rs | 4 +++- src/librustpkg/api.rs | 2 -- src/librustpkg/messages.rs | 1 - src/librustpkg/package_source.rs | 1 - src/librustpkg/util.rs | 3 ++- 14 files changed, 30 insertions(+), 60 deletions(-) diff --git a/mk/tools.mk b/mk/tools.mk index 0a901358ac1f..0e83147501cb 100644 --- a/mk/tools.mk +++ b/mk/tools.mk @@ -50,7 +50,7 @@ $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTPKG_$(4)): \ $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_EXTRALIB_$(4)) \ $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTC_$(4)) @$$(call E, compile_and_link: $$@) - $$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$< && touch $$@ + $$(STAGE$(1)_T_$(4)_H_$(3)) $$(WFLAGS_ST$(1)) -o $$@ $$< && touch $$@ $$(TBIN$(1)_T_$(4)_H_$(3))/rustpkg$$(X_$(4)): \ $$(DRIVER_CRATE) \ diff --git a/src/compiletest/common.rs b/src/compiletest/common.rs index 869657326b7d..38289f627418 100644 --- a/src/compiletest/common.rs +++ b/src/compiletest/common.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - #[deriving(Eq)] pub enum mode { mode_compile_fail, diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index 82206f12fae2..7d9a7c3ea75d 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -11,21 +11,16 @@ #[crate_type = "bin"]; #[allow(non_camel_case_types)]; +#[allow(unrecognized_lint)]; // NOTE: remove after snapshot +#[deny(warnings)]; -#[no_core]; // XXX: Remove after snapshot -#[no_std]; +extern mod extra; -extern mod core(name = "std", vers = "0.7"); -extern mod extra(name = "extra", vers = "0.7"); - -use core::prelude::*; -use core::*; +use std::os; use extra::getopts; use extra::test; -use core::result::{Ok, Err}; - use common::config; use common::mode_run_pass; use common::mode_run_fail; @@ -42,13 +37,6 @@ pub mod runtest; pub mod common; pub mod errors; -mod std { - pub use core::cmp; - pub use core::str; - pub use core::sys; - pub use core::unstable; -} - pub fn main() { let args = os::args(); let config = parse_config(args); @@ -98,8 +86,8 @@ pub fn parse_config(args: ~[~str]) -> config { run_ignored: getopts::opt_present(matches, "ignored"), filter: if !matches.free.is_empty() { - option::Some(copy matches.free[0]) - } else { option::None }, + Some(copy matches.free[0]) + } else { None }, logfile: getopts::opt_maybe_str(matches, "logfile").map(|s| Path(*s)), runtool: getopts::opt_maybe_str(matches, "runtool"), rustcflags: getopts::opt_maybe_str(matches, "rustcflags"), @@ -148,8 +136,8 @@ pub fn log_config(config: &config) { pub fn opt_str<'a>(maybestr: &'a Option<~str>) -> &'a str { match *maybestr { - option::None => "(none)", - option::Some(ref s) => { + None => "(none)", + Some(ref s) => { let s: &'a str = *s; s } @@ -161,7 +149,7 @@ pub fn opt_str2(maybestr: Option<~str>) -> ~str { } pub fn str_opt(maybestr: ~str) -> Option<~str> { - if maybestr != ~"(none)" { option::Some(maybestr) } else { option::None } + if maybestr != ~"(none)" { Some(maybestr) } else { None } } pub fn str_mode(s: ~str) -> mode { @@ -199,8 +187,8 @@ pub fn test_opts(config: &config) -> test::TestOpts { logfile: copy config.logfile, run_tests: true, run_benchmarks: false, - save_results: option::None, - compare_results: option::None + save_results: None, + compare_results: None } } @@ -268,7 +256,7 @@ pub fn make_test_name(config: &config, testfile: &Path) -> test::TestName { } pub fn make_test_closure(config: &config, testfile: &Path) -> test::TestFn { - use core::cell::Cell; + use std::cell::Cell; let config = Cell::new(copy *config); let testfile = Cell::new(testfile.to_str()); test::DynTestFn(|| { runtest::run(config.take(), testfile.take()) }) diff --git a/src/compiletest/errors.rs b/src/compiletest/errors.rs index 4649d4dfc3c4..780a917c019b 100644 --- a/src/compiletest/errors.rs +++ b/src/compiletest/errors.rs @@ -8,9 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - -use core::io; +use std::io; pub struct ExpectedError { line: uint, kind: ~str, msg: ~str } diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs index ddb68d481167..9cd489f05766 100644 --- a/src/compiletest/header.rs +++ b/src/compiletest/header.rs @@ -8,13 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use common::config; use common; -use core::io; -use core::os; +use std::io; +use std::os; pub struct TestProps { // Lines that should be expected, in order, on standard out diff --git a/src/compiletest/procsrv.rs b/src/compiletest/procsrv.rs index 93fe258d167e..0e61b45d6199 100644 --- a/src/compiletest/procsrv.rs +++ b/src/compiletest/procsrv.rs @@ -8,11 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - -use core::os; -use core::run; -use core::str; +use std::os; +use std::run; +use std::str; #[cfg(target_os = "win32")] fn target_env(lib_path: &str, prog: &str) -> ~[(~str,~str)] { diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 8e493fd5396f..91016ba91fa5 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use common::mode_run_pass; use common::mode_run_fail; use common::mode_compile_fail; @@ -22,10 +20,10 @@ use procsrv; use util; use util::logv; -use core::io; -use core::os; -use core::uint; -use core::vec; +use std::io; +use std::os; +use std::uint; +use std::vec; pub fn run(config: config, testfile: ~str) { if config.verbose { diff --git a/src/compiletest/util.rs b/src/compiletest/util.rs index 26a62f8a5b22..5af469ff8417 100644 --- a/src/compiletest/util.rs +++ b/src/compiletest/util.rs @@ -8,12 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use common::config; -use core::io; -use core::os::getenv; +use std::io; +use std::os::getenv; pub fn make_new_path(path: &str) -> ~str { diff --git a/src/driver/driver.rs b/src/driver/driver.rs index 0f61ede4fc59..e81a3230e134 100644 --- a/src/driver/driver.rs +++ b/src/driver/driver.rs @@ -8,11 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[no_core]; -#[no_std]; - -extern mod core(name = "std", vers = "0.7"); - #[cfg(rustpkg)] extern mod this(name = "rustpkg"); diff --git a/src/librusti/rusti.rs b/src/librusti/rusti.rs index bdbbcfc2b665..9911ca699dac 100644 --- a/src/librusti/rusti.rs +++ b/src/librusti/rusti.rs @@ -667,8 +667,10 @@ mod tests { fn f() {} f() "); + } - debug!("simultaneous definitions + expressions are allowed"); + #[test] + fn simultaneous_definition_and_expression() { run_program(" let a = 3; a as u8 "); diff --git a/src/librustpkg/api.rs b/src/librustpkg/api.rs index c36c6390a759..5233b87f7e4f 100644 --- a/src/librustpkg/api.rs +++ b/src/librustpkg/api.rs @@ -14,10 +14,8 @@ use package_id::*; use package_source::*; use version::Version; -use std::option::*; use std::os; use std::hashmap::*; -use std::path::*; /// Convenience functions intended for calling from pkg.rs diff --git a/src/librustpkg/messages.rs b/src/librustpkg/messages.rs index eec33a375355..96c99a7a0f17 100644 --- a/src/librustpkg/messages.rs +++ b/src/librustpkg/messages.rs @@ -10,7 +10,6 @@ use extra::term; use std::io; -use std::result::*; pub fn note(msg: &str) { pretty_message(msg, "note: ", term::color::GREEN, io::stdout()) diff --git a/src/librustpkg/package_source.rs b/src/librustpkg/package_source.rs index 24c1bb9b200f..b2f608bd352a 100644 --- a/src/librustpkg/package_source.rs +++ b/src/librustpkg/package_source.rs @@ -11,7 +11,6 @@ use target::*; use package_id::PkgId; use std::path::Path; -use std::option::*; use std::{os, run, str}; use context::*; use crate::Crate; diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index 1e99a3fa4bcd..8a57cd4b25c0 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::{libc, os, result, str}; +use std::{os, result}; use rustc::driver::{driver, session}; use rustc::metadata::filesearch; use extra::getopts::groups::getopts; @@ -379,6 +379,7 @@ pub fn link_exe(_src: &Path, _dest: &Path) -> bool { #[cfg(target_os = "freebsd")] #[cfg(target_os = "macos")] pub fn link_exe(src: &Path, dest: &Path) -> bool { + use std::{libc, str}; unsafe { do str::as_c_str(src.to_str()) |src_buf| { do str::as_c_str(dest.to_str()) |dest_buf| { From bbfef92e3d2a5e325668e07137dc531aff35a323 Mon Sep 17 00:00:00 2001 From: Chris Morgan Date: Fri, 5 Jul 2013 10:16:04 +1000 Subject: [PATCH 46/93] Move `extra::net_*` to `extra::net::*` properly. Where * = tcp, ip, url. Formerly, extra::net::* were aliases of extra::net_*, but were the recommended path to use. Thus, the documentation talked of the `net_*` modules while everything else was written expecting `net::*`. This moves the actual modules so that `extra::net::*` is the actual location of the modules. This will naturally break any code which used `extra::net_*` directly. They should be altered to use `extra::net::*` (which has been the documented way of doing things for some time). This ensures that there is one, and only one, obvious way of doing things. --- src/libextra/extra.rs | 4 +-- src/libextra/{net_ip.rs => net/ip.rs} | 34 ++++++++++++------------- src/libextra/{net.rs => net/mod.rs} | 12 ++++----- src/libextra/{net_tcp.rs => net/tcp.rs} | 2 +- src/libextra/{net_url.rs => net/url.rs} | 2 +- 5 files changed, 26 insertions(+), 28 deletions(-) rename src/libextra/{net_ip.rs => net/ip.rs} (94%) rename src/libextra/{net.rs => net/mod.rs} (86%) rename src/libextra/{net_tcp.rs => net/tcp.rs} (99%) rename src/libextra/{net_url.rs => net/url.rs} (99%) diff --git a/src/libextra/extra.rs b/src/libextra/extra.rs index 50c57b28d223..2d222099f2dc 100644 --- a/src/libextra/extra.rs +++ b/src/libextra/extra.rs @@ -40,10 +40,8 @@ pub mod uv_ll; // General io and system-services modules +#[path = "net/mod.rs"] pub mod net; -pub mod net_ip; -pub mod net_tcp; -pub mod net_url; // libuv modules pub mod uv; diff --git a/src/libextra/net_ip.rs b/src/libextra/net/ip.rs similarity index 94% rename from src/libextra/net_ip.rs rename to src/libextra/net/ip.rs index d18aac684813..8db5c65b7507 100644 --- a/src/libextra/net_ip.rs +++ b/src/libextra/net/ip.rs @@ -22,20 +22,20 @@ use std::str; use iotask = uv::iotask::IoTask; use interact = uv::iotask::interact; -use sockaddr_in = super::uv_ll::sockaddr_in; -use sockaddr_in6 = super::uv_ll::sockaddr_in6; -use addrinfo = super::uv_ll::addrinfo; -use uv_getaddrinfo_t = super::uv_ll::uv_getaddrinfo_t; -use uv_ip4_name = super::uv_ll::ip4_name; -use uv_ip4_port = super::uv_ll::ip4_port; -use uv_ip6_name = super::uv_ll::ip6_name; -use uv_ip6_port = super::uv_ll::ip6_port; -use uv_getaddrinfo = super::uv_ll::getaddrinfo; -use uv_freeaddrinfo = super::uv_ll::freeaddrinfo; -use create_uv_getaddrinfo_t = super::uv_ll::getaddrinfo_t; -use set_data_for_req = super::uv_ll::set_data_for_req; -use get_data_for_req = super::uv_ll::get_data_for_req; -use ll = super::uv_ll; +use sockaddr_in = super::super::uv_ll::sockaddr_in; +use sockaddr_in6 = super::super::uv_ll::sockaddr_in6; +use addrinfo = super::super::uv_ll::addrinfo; +use uv_getaddrinfo_t = super::super::uv_ll::uv_getaddrinfo_t; +use uv_ip4_name = super::super::uv_ll::ip4_name; +use uv_ip4_port = super::super::uv_ll::ip4_port; +use uv_ip6_name = super::super::uv_ll::ip6_name; +use uv_ip6_port = super::super::uv_ll::ip6_port; +use uv_getaddrinfo = super::super::uv_ll::getaddrinfo; +use uv_freeaddrinfo = super::super::uv_ll::freeaddrinfo; +use create_uv_getaddrinfo_t = super::super::uv_ll::getaddrinfo_t; +use set_data_for_req = super::super::uv_ll::set_data_for_req; +use get_data_for_req = super::super::uv_ll::get_data_for_req; +use ll = super::super::uv_ll; /// An IP address pub enum IpAddr { @@ -363,9 +363,9 @@ extern fn get_addr_cb(handle: *uv_getaddrinfo_t, #[cfg(test)] mod test { - use net_ip::*; - use net_ip::v4; - use net_ip::v6; + use net::ip::*; + use net::ip::v4; + use net::ip::v6; use uv; use std::result; diff --git a/src/libextra/net.rs b/src/libextra/net/mod.rs similarity index 86% rename from src/libextra/net.rs rename to src/libextra/net/mod.rs index ca1cc1235961..463260bd3dcd 100644 --- a/src/libextra/net.rs +++ b/src/libextra/net/mod.rs @@ -13,13 +13,13 @@ Top-level module for network-related functionality. Basically, including this module gives you: -* `net_tcp` -* `net_ip` -* `net_url` +* `tcp` +* `ip` +* `url` See each of those three modules for documentation on what they do. */ -pub use tcp = net_tcp; -pub use ip = net_ip; -pub use url = net_url; +pub mod tcp; +pub mod ip; +pub mod url; diff --git a/src/libextra/net_tcp.rs b/src/libextra/net/tcp.rs similarity index 99% rename from src/libextra/net_tcp.rs rename to src/libextra/net/tcp.rs index 6a22950ec04b..e0ed313bc026 100644 --- a/src/libextra/net_tcp.rs +++ b/src/libextra/net/tcp.rs @@ -16,7 +16,7 @@ use future; use future_spawn = future::spawn; -use ip = net_ip; +use ip = net::ip; use uv; use uv::iotask; use uv::iotask::IoTask; diff --git a/src/libextra/net_url.rs b/src/libextra/net/url.rs similarity index 99% rename from src/libextra/net_url.rs rename to src/libextra/net/url.rs index 9ac58efe7930..4ed8761cc11b 100644 --- a/src/libextra/net_url.rs +++ b/src/libextra/net/url.rs @@ -800,7 +800,7 @@ fn test_get_path() { #[cfg(test)] mod tests { - use net_url::*; + use net::url::*; use std::hashmap::HashMap; From b6024e4ca27bda4846b1a7829f098caf4d140f71 Mon Sep 17 00:00:00 2001 From: Chris Morgan Date: Fri, 5 Jul 2013 13:07:10 +1000 Subject: [PATCH 47/93] Remove superfluous super::super:: --- src/libextra/net/ip.rs | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/libextra/net/ip.rs b/src/libextra/net/ip.rs index 8db5c65b7507..bf58f81ef0e3 100644 --- a/src/libextra/net/ip.rs +++ b/src/libextra/net/ip.rs @@ -22,20 +22,20 @@ use std::str; use iotask = uv::iotask::IoTask; use interact = uv::iotask::interact; -use sockaddr_in = super::super::uv_ll::sockaddr_in; -use sockaddr_in6 = super::super::uv_ll::sockaddr_in6; -use addrinfo = super::super::uv_ll::addrinfo; -use uv_getaddrinfo_t = super::super::uv_ll::uv_getaddrinfo_t; -use uv_ip4_name = super::super::uv_ll::ip4_name; -use uv_ip4_port = super::super::uv_ll::ip4_port; -use uv_ip6_name = super::super::uv_ll::ip6_name; -use uv_ip6_port = super::super::uv_ll::ip6_port; -use uv_getaddrinfo = super::super::uv_ll::getaddrinfo; -use uv_freeaddrinfo = super::super::uv_ll::freeaddrinfo; -use create_uv_getaddrinfo_t = super::super::uv_ll::getaddrinfo_t; -use set_data_for_req = super::super::uv_ll::set_data_for_req; -use get_data_for_req = super::super::uv_ll::get_data_for_req; -use ll = super::super::uv_ll; +use sockaddr_in = uv_ll::sockaddr_in; +use sockaddr_in6 = uv_ll::sockaddr_in6; +use addrinfo = uv_ll::addrinfo; +use uv_getaddrinfo_t = uv_ll::uv_getaddrinfo_t; +use uv_ip4_name = uv_ll::ip4_name; +use uv_ip4_port = uv_ll::ip4_port; +use uv_ip6_name = uv_ll::ip6_name; +use uv_ip6_port = uv_ll::ip6_port; +use uv_getaddrinfo = uv_ll::getaddrinfo; +use uv_freeaddrinfo = uv_ll::freeaddrinfo; +use create_uv_getaddrinfo_t = uv_ll::getaddrinfo_t; +use set_data_for_req = uv_ll::set_data_for_req; +use get_data_for_req = uv_ll::get_data_for_req; +use ll = uv_ll; /// An IP address pub enum IpAddr { From c9b9462e8f7f0181fcc7f5883c4502e81d260b12 Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Tue, 2 Jul 2013 15:46:27 +0900 Subject: [PATCH 48/93] Remove visit_struct_method --- src/librustc/middle/lint.rs | 12 ------------ src/libsyntax/visit.rs | 12 ------------ 2 files changed, 24 deletions(-) diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index ce9ab790b11b..c39b676b97f0 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -966,10 +966,6 @@ fn lint_unused_mut() -> visit::vt<@mut Context> { visit_fn_decl(cx, &tm.decl); visit::visit_ty_method(tm, (cx, vt)); }, - visit_struct_method: |sm, (cx, vt)| { - visit_fn_decl(cx, &sm.decl); - visit::visit_struct_method(sm, (cx, vt)); - }, visit_trait_method: |tm, (cx, vt)| { match *tm { ast::required(ref tm) => visit_fn_decl(cx, &tm.decl), @@ -1049,14 +1045,6 @@ fn lint_missing_doc() -> visit::vt<@mut Context> { } visit::mk_vt(@visit::Visitor { - visit_struct_method: |m, (cx, vt)| { - if m.vis == ast::public { - check_attrs(cx, m.attrs, m.span, - "missing documentation for a method"); - } - visit::visit_struct_method(m, (cx, vt)); - }, - visit_ty_method: |m, (cx, vt)| { // All ty_method objects are linted about because they're part of a // trait (no visibility) diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 9fcffc110130..5bde51ad70fa 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -90,7 +90,6 @@ pub struct Visitor { visit_trait_method: @fn(&trait_method, (E, vt)), visit_struct_def: @fn(@struct_def, ident, &Generics, node_id, (E, vt)), visit_struct_field: @fn(@struct_field, (E, vt)), - visit_struct_method: @fn(@method, (E, vt)) } pub type visitor = @Visitor; @@ -116,7 +115,6 @@ pub fn default_visitor() -> visitor { visit_trait_method: |a,b|visit_trait_method::(a, b), visit_struct_def: |a,b,c,d,e|visit_struct_def::(a, b, c, d, e), visit_struct_field: |a,b|visit_struct_field::(a, b), - visit_struct_method: |a,b|visit_struct_method::(a, b) }; } @@ -414,10 +412,6 @@ pub fn visit_struct_field(sf: &struct_field, (e, v): (E, vt)) { (v.visit_ty)(sf.node.ty, (e, v)); } -pub fn visit_struct_method(m: &method, (e, v): (E, vt)) { - visit_method_helper(m, (e, v)); -} - pub fn visit_block(b: &blk, (e, v): (E, vt)) { for b.node.view_items.iter().advance |vi| { (v.visit_view_item)(*vi, (copy e, v)); @@ -729,10 +723,6 @@ pub fn mk_simple_visitor(v: simple_visitor) -> vt<()> { f(sf); visit_struct_field(sf, (e, v)); } - fn v_struct_method(f: @fn(@method), m: @method, (e, v): ((), vt<()>)) { - f(m); - visit_struct_method(m, (e, v)); - } return mk_vt(@Visitor { visit_mod: |a,b,c,d|v_mod(v.visit_mod, a, b, c, d), visit_view_item: |a,b| v_view_item(v.visit_view_item, a, b), @@ -760,7 +750,5 @@ pub fn mk_simple_visitor(v: simple_visitor) -> vt<()> { v_struct_def(v.visit_struct_def, a, b, c, d, e), visit_struct_field: |a,b| v_struct_field(v.visit_struct_field, a, b), - visit_struct_method: |a,b| - v_struct_method(v.visit_struct_method, a, b) }); } From 2e65782c1780cb9327281c7f78c8b40a5b4f5f57 Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Tue, 2 Jul 2013 18:31:00 +0900 Subject: [PATCH 49/93] Do not rely on newtype enum dereference --- src/librustc/front/test.rs | 6 +++--- src/libsyntax/codemap.rs | 11 +++-------- src/libsyntax/ext/base.rs | 17 +++++++---------- src/libsyntax/ext/expand.rs | 22 +++++++++++----------- src/libsyntax/ext/source_util.rs | 10 +++++----- 5 files changed, 29 insertions(+), 37 deletions(-) diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs index 91000d68aad0..bbac4a2907c0 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -17,7 +17,7 @@ use front::config; use std::vec; use syntax::ast_util::*; use syntax::attr; -use syntax::codemap::{dummy_sp, span, ExpandedFrom, CallInfo, NameAndSpan}; +use syntax::codemap::{dummy_sp, span, ExpnInfo, NameAndSpan}; use syntax::codemap; use syntax::ext::base::ExtCtxt; use syntax::fold; @@ -72,13 +72,13 @@ fn generate_test_harness(sess: session::Session, }; let ext_cx = cx.ext_cx; - ext_cx.bt_push(ExpandedFrom(CallInfo { + ext_cx.bt_push(ExpnInfo { call_site: dummy_sp(), callee: NameAndSpan { name: @"test", span: None } - })); + }); let precursor = @fold::AstFoldFns { fold_crate: fold::wrap(|a,b| fold_crate(cx, a, b) ), diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index bcf617c56ae1..7e89d0407816 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -174,16 +174,11 @@ pub struct FileMapAndBytePos {fm: @FileMap, pos: BytePos} #[deriving(IterBytes)] pub struct NameAndSpan {name: @str, span: Option} -#[deriving(IterBytes)] -pub struct CallInfo { - call_site: span, - callee: NameAndSpan -} - /// Extra information for tracking macro expansion of spans #[deriving(IterBytes)] -pub enum ExpnInfo { - ExpandedFrom(CallInfo) +pub struct ExpnInfo { + call_site: span, + callee: NameAndSpan } pub type FileName = @str; diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 78fdb99753d4..ad14b567b960 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -11,8 +11,7 @@ use ast; use ast::Name; use codemap; -use codemap::{CodeMap, span, ExpnInfo, ExpandedFrom}; -use codemap::CallInfo; +use codemap::{CodeMap, span, ExpnInfo}; use diagnostic::span_handler; use ext; use parse; @@ -243,7 +242,7 @@ impl ExtCtxt { pub fn cfg(&self) -> ast::crate_cfg { copy self.cfg } pub fn call_site(&self) -> span { match *self.backtrace { - Some(@ExpandedFrom(CallInfo {call_site: cs, _})) => cs, + Some(@ExpnInfo {call_site: cs, _}) => cs, None => self.bug("missing top span") } } @@ -254,21 +253,19 @@ impl ExtCtxt { pub fn mod_path(&self) -> ~[ast::ident] { copy *self.mod_path } pub fn bt_push(&self, ei: codemap::ExpnInfo) { match ei { - ExpandedFrom(CallInfo {call_site: cs, callee: ref callee}) => { + ExpnInfo {call_site: cs, callee: ref callee} => { *self.backtrace = - Some(@ExpandedFrom(CallInfo { + Some(@ExpnInfo { call_site: span {lo: cs.lo, hi: cs.hi, expn_info: *self.backtrace}, - callee: copy *callee})); + callee: copy *callee}); } } } pub fn bt_pop(&self) { match *self.backtrace { - Some(@ExpandedFrom( - CallInfo { - call_site: span {expn_info: prev, _}, _ - })) => { + Some(@ExpnInfo { + call_site: span {expn_info: prev, _}, _}) => { *self.backtrace = prev } _ => self.bug("tried to pop without a push") diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index a78a18810a8d..2b18ede88791 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -16,7 +16,7 @@ use ast; use ast_util::{new_rename, new_mark, resolve}; use attr; use codemap; -use codemap::{span, CallInfo, ExpandedFrom, NameAndSpan, spanned}; +use codemap::{span, ExpnInfo, NameAndSpan, spanned}; use ext::base::*; use fold::*; use parse; @@ -60,13 +60,13 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv, expander: exp, span: exp_sp }))) => { - cx.bt_push(ExpandedFrom(CallInfo { + cx.bt_push(ExpnInfo { call_site: s, callee: NameAndSpan { name: extnamestr, span: exp_sp, }, - })); + }); let expanded = match exp(cx, mac.span, *tts) { MRExpr(e) => e, @@ -131,13 +131,13 @@ pub fn expand_mod_items(extsbox: @mut SyntaxEnv, match (*extsbox).find(&intern(mname)) { Some(@SE(ItemDecorator(dec_fn))) => { - cx.bt_push(ExpandedFrom(CallInfo { + cx.bt_push(ExpnInfo { call_site: attr.span, callee: NameAndSpan { name: mname, span: None } - })); + }); let r = dec_fn(cx, attr.span, attr.node.value, items); cx.bt_pop(); r @@ -227,13 +227,13 @@ pub fn expand_item_mac(extsbox: @mut SyntaxEnv, given '%s'", extnamestr, ident_to_str(&it.ident))); } - cx.bt_push(ExpandedFrom(CallInfo { + cx.bt_push(ExpnInfo { call_site: it.span, callee: NameAndSpan { name: extnamestr, span: expand.span } - })); + }); ((*expand).expander)(cx, it.span, tts) } Some(@SE(IdentTT(ref expand))) => { @@ -242,13 +242,13 @@ pub fn expand_item_mac(extsbox: @mut SyntaxEnv, fmt!("macro %s! expects an ident argument", extnamestr)); } - cx.bt_push(ExpandedFrom(CallInfo { + cx.bt_push(ExpnInfo { call_site: it.span, callee: NameAndSpan { name: extnamestr, span: expand.span } - })); + }); ((*expand).expander)(cx, it.span, it.ident, tts) } _ => cx.span_fatal( @@ -319,10 +319,10 @@ pub fn expand_stmt(extsbox: @mut SyntaxEnv, Some(@SE(NormalTT( SyntaxExpanderTT{expander: exp, span: exp_sp}))) => { - cx.bt_push(ExpandedFrom(CallInfo { + cx.bt_push(ExpnInfo { call_site: sp, callee: NameAndSpan { name: extnamestr, span: exp_sp } - })); + }); let expanded = match exp(cx, mac.span, tts) { MRExpr(e) => @codemap::spanned { node: stmt_expr(e, cx.next_id()), diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index f6325c2eb2c1..b43536389e2c 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -10,8 +10,8 @@ use ast; use codemap; -use codemap::{Pos, ExpandedFrom, span}; -use codemap::{CallInfo, NameAndSpan}; +use codemap::{Pos, span}; +use codemap::{ExpnInfo, NameAndSpan}; use ext::base::*; use ext::base; use ext::build::AstBuilder; @@ -117,14 +117,14 @@ pub fn expand_include_bin(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree]) // recur along an ExpnInfo chain to find the original expression fn topmost_expn_info(expn_info: @codemap::ExpnInfo) -> @codemap::ExpnInfo { match *expn_info { - ExpandedFrom(CallInfo { call_site: ref call_site, _ }) => { + ExpnInfo { call_site: ref call_site, _ } => { match call_site.expn_info { Some(next_expn_info) => { match *next_expn_info { - ExpandedFrom(CallInfo { + ExpnInfo { callee: NameAndSpan { name: ref name, _ }, _ - }) => { + } => { // Don't recurse into file using "include!" if "include" == *name { expn_info From 20458899d53074c2b503ec08a5c1ec4decb2b28f Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Thu, 4 Jul 2013 17:21:02 +0900 Subject: [PATCH 50/93] vim: Highlight 0i as number --- src/etc/vim/syntax/rust.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/etc/vim/syntax/rust.vim b/src/etc/vim/syntax/rust.vim index 25e44c62a8a7..f40bed8640dc 100644 --- a/src/etc/vim/syntax/rust.vim +++ b/src/etc/vim/syntax/rust.vim @@ -95,7 +95,7 @@ syn region rustDeriving start="deriving(" end=")" contains=rustTrait " Number literals syn match rustNumber display "\<[0-9][0-9_]*\>" syn match rustNumber display "\<[0-9][0-9_]*\(u\|u8\|u16\|u32\|u64\)\>" -syn match rustNumber display "\<[0-9][0-9_]*\(i8\|i16\|i32\|i64\)\>" +syn match rustNumber display "\<[0-9][0-9_]*\(i\|i8\|i16\|i32\|i64\)\>" syn match rustHexNumber display "\<0x[a-fA-F0-9_]\+\>" syn match rustHexNumber display "\<0x[a-fA-F0-9_]\+\(u\|u8\|u16\|u32\|u64\)\>" From 30fca57f17dea0b32500937bf80ab1039c50f9f1 Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Thu, 4 Jul 2013 20:48:45 +0900 Subject: [PATCH 51/93] Change spans for sugary call expressions --- src/libsyntax/parse/parser.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index cc0baa28e20d..ae87fd8774a9 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1549,10 +1549,10 @@ impl Parser { } else if self.eat_keyword(keywords::If) { return self.parse_if_expr(); } else if self.eat_keyword(keywords::For) { - return self.parse_sugary_call_expr(~"for", ForSugar, + return self.parse_sugary_call_expr(lo, ~"for", ForSugar, expr_loop_body); } else if self.eat_keyword(keywords::Do) { - return self.parse_sugary_call_expr(~"do", DoSugar, + return self.parse_sugary_call_expr(lo, ~"do", DoSugar, expr_do_body); } else if self.eat_keyword(keywords::While) { return self.parse_while_expr(); @@ -2264,12 +2264,11 @@ impl Parser { // parse a 'for' or 'do'. // the 'for' and 'do' expressions parse as calls, but look like // function calls followed by a closure expression. - pub fn parse_sugary_call_expr(&self, + pub fn parse_sugary_call_expr(&self, lo: BytePos, keyword: ~str, sugar: CallSugar, ctor: &fn(v: @expr) -> expr_) -> @expr { - let lo = self.last_span; // Parse the callee `foo` in // for foo || { // for foo.bar || { @@ -2286,21 +2285,21 @@ impl Parser { let last_arg = self.mk_expr(block.span.lo, block.span.hi, ctor(block)); let args = vec::append(copy *args, [last_arg]); - self.mk_expr(lo.lo, block.span.hi, expr_call(f, args, sugar)) + self.mk_expr(lo, block.span.hi, expr_call(f, args, sugar)) } expr_method_call(_, f, i, ref tps, ref args, NoSugar) => { let block = self.parse_lambda_block_expr(); let last_arg = self.mk_expr(block.span.lo, block.span.hi, ctor(block)); let args = vec::append(copy *args, [last_arg]); - self.mk_expr(lo.lo, block.span.hi, + self.mk_expr(lo, block.span.hi, self.mk_method_call(f, i, copy *tps, args, sugar)) } expr_field(f, i, ref tps) => { let block = self.parse_lambda_block_expr(); let last_arg = self.mk_expr(block.span.lo, block.span.hi, ctor(block)); - self.mk_expr(lo.lo, block.span.hi, + self.mk_expr(lo, block.span.hi, self.mk_method_call(f, i, copy *tps, ~[last_arg], sugar)) } expr_path(*) | expr_call(*) | expr_method_call(*) | @@ -2309,7 +2308,7 @@ impl Parser { let last_arg = self.mk_expr(block.span.lo, block.span.hi, ctor(block)); self.mk_expr( - lo.lo, + lo, last_arg.span.hi, self.mk_call(e, ~[last_arg], sugar)) } @@ -2319,7 +2318,7 @@ impl Parser { // but they aren't represented by tests debug!("sugary call on %?", e.node); self.span_fatal( - *lo, + e.span, fmt!("`%s` must be followed by a block call", keyword)); } } From 376d5d6aae9a448a0f58a9a98e8dcec9eeeaece7 Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Fri, 5 Jul 2013 14:56:54 +0900 Subject: [PATCH 52/93] Fix fallout from span change --- src/test/compile-fail/issue-3044.rs | 2 +- src/test/pretty/block-comment-wchar.pp | 1 - src/test/pretty/block-comment-wchar.rs | 2 +- src/test/pretty/for-comment.rs | 18 ++++++++++++++++++ 4 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 src/test/pretty/for-comment.rs diff --git a/src/test/compile-fail/issue-3044.rs b/src/test/compile-fail/issue-3044.rs index f4ae436c624d..310de3657b38 100644 --- a/src/test/compile-fail/issue-3044.rs +++ b/src/test/compile-fail/issue-3044.rs @@ -12,7 +12,7 @@ fn main() { let needlesArr: ~[char] = ~['a', 'f']; do needlesArr.iter().fold() |x, y| { } - //~^ ERROR 1 parameter was supplied (including the closure passed by the `do` keyword) + //~^^ ERROR 1 parameter was supplied (including the closure passed by the `do` keyword) // // the first error is, um, non-ideal. } diff --git a/src/test/pretty/block-comment-wchar.pp b/src/test/pretty/block-comment-wchar.pp index dbf28caecf29..c666950034a0 100644 --- a/src/test/pretty/block-comment-wchar.pp +++ b/src/test/pretty/block-comment-wchar.pp @@ -108,7 +108,6 @@ fn main() { '\xA0', '\u1680', '\u180E', '\u2000', '\u2001', '\u2002', '\u2003', '\u2004', '\u2005', '\u2006', '\u2007', '\u2008', '\u2009', '\u200A', '\u2028', '\u2029', '\u202F', '\u205F', '\u3000']; - // <= bugs in pretty-printer? for chars.iter().advance |c| { let ws = c.is_whitespace(); println(fmt!("%? %?" , c , ws)); diff --git a/src/test/pretty/block-comment-wchar.rs b/src/test/pretty/block-comment-wchar.rs index 148b50d9c912..f0d46f39cdf9 100644 --- a/src/test/pretty/block-comment-wchar.rs +++ b/src/test/pretty/block-comment-wchar.rs @@ -104,6 +104,6 @@ fn main() { '\u2028', '\u2029', '\u202F', '\u205F', '\u3000']; for chars.iter().advance |c| { let ws = c.is_whitespace(); - println(fmt!("%? %?", c , ws)); // <= bugs in pretty-printer? + println(fmt!("%? %?", c , ws)); } } diff --git a/src/test/pretty/for-comment.rs b/src/test/pretty/for-comment.rs new file mode 100644 index 000000000000..15631337d2a4 --- /dev/null +++ b/src/test/pretty/for-comment.rs @@ -0,0 +1,18 @@ +// Copyright 2013 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// pp-exact + +fn f(v: &[int]) { + let mut n = 0; + for v.iter().advance |e| { + n = *e; // This comment once triggered pretty printer bug + } +} From dc9b3ff1b30c10aaf60d40fd9845d9bf69ae2c2e Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Tue, 2 Jul 2013 18:40:46 -0700 Subject: [PATCH 53/93] Change signature of Iterator.size_hint Remove the Option wrapper around the lower bound. None is semantically the same as Size(0), so there's no point in having a distinction. --- src/librustc/util/enum_set.rs | 6 +++--- src/libstd/iterator.rs | 21 ++++++++------------- src/libstd/vec.rs | 28 ++++++++++++++-------------- 3 files changed, 25 insertions(+), 30 deletions(-) diff --git a/src/librustc/util/enum_set.rs b/src/librustc/util/enum_set.rs index f9bd7a3508ed..3ce645e012b7 100644 --- a/src/librustc/util/enum_set.rs +++ b/src/librustc/util/enum_set.rs @@ -125,9 +125,9 @@ impl Iterator for EnumSetIterator { Some(elem) } - fn size_hint(&self) -> (Option, Option) { - let exact = Some(self.bits.population_count()); - (exact, exact) + fn size_hint(&self) -> (uint, Option) { + let exact = self.bits.population_count(); + (exact, Some(exact)) } } diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index 77befbf19aa9..46d449e4dfb8 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -43,7 +43,7 @@ pub trait Iterator { /// Return a lower bound and upper bound on the remaining length of the iterator. /// /// The common use case for the estimate is pre-allocating space to store the results. - fn size_hint(&self) -> (Option, Option) { (None, None) } + fn size_hint(&self) -> (uint, Option) { (0, None) } } /// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also @@ -684,16 +684,11 @@ impl, U: Iterator> Iterator for ChainIterator { } #[inline] - fn size_hint(&self) -> (Option, Option) { + fn size_hint(&self) -> (uint, Option) { let (a_lower, a_upper) = self.a.size_hint(); let (b_lower, b_upper) = self.b.size_hint(); - let lower = match (a_lower, b_lower) { - (Some(x), Some(y)) => Some(x + y), - (Some(x), None) => Some(x), - (None, Some(y)) => Some(y), - (None, None) => None - }; + let lower = a_lower + b_lower; let upper = match (a_upper, b_upper) { (Some(x), Some(y)) => Some(x + y), @@ -737,7 +732,7 @@ impl<'self, A, B, T: Iterator> Iterator for MapIterator<'self, A, B, T> { } #[inline] - fn size_hint(&self) -> (Option, Option) { + fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } } @@ -762,9 +757,9 @@ impl<'self, A, T: Iterator> Iterator for FilterIterator<'self, A, T> { } #[inline] - fn size_hint(&self) -> (Option, Option) { + fn size_hint(&self) -> (uint, Option) { let (_, upper) = self.iter.size_hint(); - (None, upper) // can't know a lower bound, due to the predicate + (0, upper) // can't know a lower bound, due to the predicate } } @@ -787,9 +782,9 @@ impl<'self, A, B, T: Iterator> Iterator for FilterMapIterator<'self, A, B, } #[inline] - fn size_hint(&self) -> (Option, Option) { + fn size_hint(&self) -> (uint, Option) { let (_, upper) = self.iter.size_hint(); - (None, upper) // can't know a lower bound, due to the predicate + (0, upper) // can't know a lower bound, due to the predicate } } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 1014ff48b1d2..7244a9a7aac5 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -2024,14 +2024,14 @@ macro_rules! iterator { } #[inline] - fn size_hint(&self) -> (Option, Option) { + fn size_hint(&self) -> (uint, Option) { let diff = if $step > 0 { (self.end as uint) - (self.ptr as uint) } else { (self.ptr as uint) - (self.end as uint) }; - let exact = Some(diff / size_of::<$elem>()); - (exact, exact) + let exact = diff / size_of::<$elem>(); + (exact, Some(exact)) } } } @@ -2132,7 +2132,7 @@ impl> FromIterator for ~[A] { impl> FromIterator for ~[A] { pub fn from_iterator(iterator: &mut T) -> ~[A] { let (lower, _) = iterator.size_hint(); - let mut xs = with_capacity(lower.get_or_zero()); + let mut xs = with_capacity(lower); for iterator.advance |x| { xs.push(x); } @@ -2968,17 +2968,17 @@ mod tests { use iterator::*; let xs = [1, 2, 5, 10, 11]; let mut it = xs.iter(); - assert_eq!(it.size_hint(), (Some(5), Some(5))); + assert_eq!(it.size_hint(), (5, Some(5))); assert_eq!(it.next().unwrap(), &1); - assert_eq!(it.size_hint(), (Some(4), Some(4))); + assert_eq!(it.size_hint(), (4, Some(4))); assert_eq!(it.next().unwrap(), &2); - assert_eq!(it.size_hint(), (Some(3), Some(3))); + assert_eq!(it.size_hint(), (3, Some(3))); assert_eq!(it.next().unwrap(), &5); - assert_eq!(it.size_hint(), (Some(2), Some(2))); + assert_eq!(it.size_hint(), (2, Some(2))); assert_eq!(it.next().unwrap(), &10); - assert_eq!(it.size_hint(), (Some(1), Some(1))); + assert_eq!(it.size_hint(), (1, Some(1))); assert_eq!(it.next().unwrap(), &11); - assert_eq!(it.size_hint(), (Some(0), Some(0))); + assert_eq!(it.size_hint(), (0, Some(0))); assert!(it.next().is_none()); } @@ -2986,10 +2986,10 @@ mod tests { fn test_iter_size_hints() { use iterator::*; let mut xs = [1, 2, 5, 10, 11]; - assert_eq!(xs.iter().size_hint(), (Some(5), Some(5))); - assert_eq!(xs.rev_iter().size_hint(), (Some(5), Some(5))); - assert_eq!(xs.mut_iter().size_hint(), (Some(5), Some(5))); - assert_eq!(xs.mut_rev_iter().size_hint(), (Some(5), Some(5))); + assert_eq!(xs.iter().size_hint(), (5, Some(5))); + assert_eq!(xs.rev_iter().size_hint(), (5, Some(5))); + assert_eq!(xs.mut_iter().size_hint(), (5, Some(5))); + assert_eq!(xs.mut_rev_iter().size_hint(), (5, Some(5))); } #[test] From 20016b92c8c03e33ad9b965fba32ac851fe9f6bf Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Tue, 2 Jul 2013 20:59:26 -0700 Subject: [PATCH 54/93] Implement .size_hint() on the remaining Iterator adaptors Every iterator adaptor now has an implementation of .size_hint() that makes sense, except for when the default of (0, None) is correct. --- src/libstd/iterator.rs | 119 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 118 insertions(+), 1 deletion(-) diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index 46d449e4dfb8..b164bcbd28b3 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -26,6 +26,7 @@ use option::{Option, Some, None}; use ops::{Add, Mul}; use cmp::Ord; use clone::Clone; +use uint; /// Conversion from an `Iterator` pub trait FromIterator> { @@ -688,9 +689,14 @@ impl, U: Iterator> Iterator for ChainIterator { let (a_lower, a_upper) = self.a.size_hint(); let (b_lower, b_upper) = self.b.size_hint(); - let lower = a_lower + b_lower; + let lower = if uint::max_value - a_lower < b_lower { + uint::max_value + } else { + a_lower + b_lower + }; let upper = match (a_upper, b_upper) { + (Some(x), Some(y)) if uint::max_value - x < y => Some(uint::max_value), (Some(x), Some(y)) => Some(x + y), _ => None }; @@ -714,6 +720,23 @@ impl, U: Iterator> Iterator<(A, B)> for ZipIterator None } } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + let (a_lower, a_upper) = self.a.size_hint(); + let (b_lower, b_upper) = self.b.size_hint(); + + let lower = cmp::min(a_lower, b_lower); + + let upper = match (a_upper, b_upper) { + (Some(x), Some(y)) => Some(cmp::min(x,y)), + (Some(x), None) => Some(x), + (None, Some(y)) => Some(y), + (None, None) => None + }; + + (lower, upper) + } } /// An iterator which maps the values of `iter` with `f` @@ -807,6 +830,11 @@ impl> Iterator<(uint, A)> for EnumerateIterator { _ => None } } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + self.iter.size_hint() + } } /// An iterator which rejects elements while `predicate` is true @@ -839,6 +867,12 @@ impl<'self, A, T: Iterator> Iterator for SkipWhileIterator<'self, A, T> { } } } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) // can't know a lower bound, due to the predicate + } } /// An iterator which only accepts elements while `predicate` is true @@ -867,6 +901,12 @@ impl<'self, A, T: Iterator> Iterator for TakeWhileIterator<'self, A, T> { } } } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) // can't know a lower bound, due to the predicate + } } /// An iterator which skips over `n` elements of `iter`. @@ -900,6 +940,21 @@ impl> Iterator for SkipIterator { next } } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + let (lower, upper) = self.iter.size_hint(); + + let lower = if lower >= self.n { lower - self.n } else { 0 }; + + let upper = match upper { + Some(x) if x >= self.n => Some(x - self.n), + Some(_) => Some(0), + None => None + }; + + (lower, upper) + } } /// An iterator which only iterates over the first `n` iterations of `iter`. @@ -920,6 +975,20 @@ impl> Iterator for TakeIterator { None } } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + let (lower, upper) = self.iter.size_hint(); + + let lower = cmp::min(lower, self.n); + + let upper = match upper { + Some(x) if x < self.n => Some(x), + _ => Some(self.n) + }; + + (lower, upper) + } } /// An iterator to maintain state while iterating another iterator @@ -936,6 +1005,12 @@ impl<'self, A, B, T: Iterator, St> Iterator for ScanIterator<'self, A, B, fn next(&mut self) -> Option { self.iter.next().chain(|a| (self.f)(&mut self.state, a)) } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) // can't know a lower bound, due to the scan function + } } /// An iterator that maps each element to an iterator, @@ -1017,6 +1092,11 @@ impl + Clone> Iterator for Counter { self.state = self.state.add(&self.step); // FIXME: #6050 Some(result) } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + (uint::max_value, None) // Too bad we can't specify an infinite lower bound + } } #[cfg(test)] @@ -1232,6 +1312,43 @@ mod tests { assert_eq!(v.slice(0, 0).iter().transform(|&x| x).min(), None); } + #[test] + fn test_iterator_size_hint() { + let c = Counter::new(0, 1); + let v = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + let v2 = &[10, 11, 12]; + let vi = v.iter(); + + assert_eq!(c.size_hint(), (uint::max_value, None)); + assert_eq!(vi.size_hint(), (10, Some(10))); + + assert_eq!(c.take_(5).size_hint(), (5, Some(5))); + assert_eq!(c.skip(5).size_hint().second(), None); + assert_eq!(c.take_while(|_| false).size_hint(), (0, None)); + assert_eq!(c.skip_while(|_| false).size_hint(), (0, None)); + assert_eq!(c.enumerate().size_hint(), (uint::max_value, None)); + assert_eq!(c.chain_(vi.transform(|&i| i)).size_hint(), (uint::max_value, None)); + assert_eq!(c.zip(vi).size_hint(), (10, Some(10))); + assert_eq!(c.scan(0, |_,_| Some(0)).size_hint(), (0, None)); + assert_eq!(c.filter(|_| false).size_hint(), (0, None)); + assert_eq!(c.transform(|_| 0).size_hint(), (uint::max_value, None)); + assert_eq!(c.filter_map(|_| Some(0)).size_hint(), (0, None)); + + assert_eq!(vi.take_(5).size_hint(), (5, Some(5))); + assert_eq!(vi.take_(12).size_hint(), (10, Some(10))); + assert_eq!(vi.skip(3).size_hint(), (7, Some(7))); + assert_eq!(vi.skip(12).size_hint(), (0, Some(0))); + assert_eq!(vi.take_while(|_| false).size_hint(), (0, Some(10))); + assert_eq!(vi.skip_while(|_| false).size_hint(), (0, Some(10))); + assert_eq!(vi.enumerate().size_hint(), (10, Some(10))); + assert_eq!(vi.chain_(v2.iter()).size_hint(), (13, Some(13))); + assert_eq!(vi.zip(v2.iter()).size_hint(), (3, Some(3))); + assert_eq!(vi.scan(0, |_,_| Some(0)).size_hint(), (0, Some(10))); + assert_eq!(vi.filter(|_| false).size_hint(), (0, Some(10))); + assert_eq!(vi.transform(|i| i+1).size_hint(), (10, Some(10))); + assert_eq!(vi.filter_map(|_| Some(0)).size_hint(), (0, Some(10))); + } + #[test] fn test_collect() { let a = ~[1, 2, 3, 4, 5]; From d805b832f5a49acc66e0d2acda9f9f4cf074a374 Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Fri, 5 Jul 2013 20:32:25 +0200 Subject: [PATCH 55/93] vec: Add .pop_opt() -> Option Add a function to safely retrieve the last element of a ~[T], as Option. Implement pop() using pop_opt(); it benches the same as the old implementation when tested with optimization level 2. --- src/libstd/vec.rs | 62 +++++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 1014ff48b1d2..7ae4e8a1d2fb 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -1091,6 +1091,7 @@ pub trait OwnedVector { fn push_all_move(&mut self, rhs: ~[T]); fn pop(&mut self) -> T; + fn pop_opt(&mut self) -> Option; fn shift(&mut self) -> T; fn unshift(&mut self, x: T); fn insert(&mut self, i: uint, x:T); @@ -1281,18 +1282,26 @@ impl OwnedVector for ~[T] { } } - /// Remove the last element from a vector and return it + /// Remove the last element from a vector and return it, or `None` if it is empty + fn pop_opt(&mut self) -> Option { + match self.len() { + 0 => None, + ln => { + let valptr = ptr::to_mut_unsafe_ptr(&mut self[ln - 1u]); + unsafe { + let val = ptr::replace_ptr(valptr, intrinsics::init()); + raw::set_len(self, ln - 1u); + Some(val) + } + } + } + } + + + /// Remove the last element from a vector and return it, failing if it is empty + #[inline] fn pop(&mut self) -> T { - let ln = self.len(); - if ln == 0 { - fail!("sorry, cannot pop an empty vector") - } - let valptr = ptr::to_mut_unsafe_ptr(&mut self[ln - 1u]); - unsafe { - let val = ptr::replace_ptr(valptr, intrinsics::init()); - raw::set_len(self, ln - 1u); - val - } + self.pop_opt().expect("pop: empty vector") } /// Removes the first element from a vector and return it @@ -2089,18 +2098,13 @@ impl Iterator for VecConsumeIterator { // // [1,2,3,4,5] => 1, [5,2,3,4] => 2, [5,4,3] => 3, [5,4] => 4, // [5] -> 5, [] - - if self.v.is_empty() { - None - } else { - let l = self.v.len(); - if self.idx < l { - self.v.swap(self.idx, l - 1); - self.idx += 1; - } - - Some(self.v.pop()) + let l = self.v.len(); + if self.idx < l { + self.v.swap(self.idx, l - 1); + self.idx += 1; } + + self.v.pop_opt() } } @@ -2111,8 +2115,7 @@ pub struct VecConsumeRevIterator { impl Iterator for VecConsumeRevIterator { fn next(&mut self) -> Option { - if self.v.is_empty() { None } - else { Some(self.v.pop()) } + self.v.pop_opt() } } @@ -2415,6 +2418,17 @@ mod tests { } #[test] + fn test_pop_opt() { + let mut v = ~[5]; + let e = v.pop_opt(); + assert_eq!(v.len(), 0); + assert_eq!(e, Some(5)); + let f = v.pop_opt(); + assert_eq!(f, None); + let g = v.pop_opt(); + assert_eq!(g, None); + } + fn test_swap_remove() { let mut v = ~[1, 2, 3, 4, 5]; let mut e = v.swap_remove(0); From fc17d4371f1d3e0c40ebcb6de0b9e7cbb89fa0c9 Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Fri, 5 Jul 2013 20:32:25 +0200 Subject: [PATCH 56/93] vec: Add .shift_opt() -> Option Add a function to safely retrieve the first element of a ~[T], as Option. Implement shift() using shift_opt(). Add tests for both .shift() and .shift_opt() --- src/libstd/vec.rs | 52 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 7ae4e8a1d2fb..199852deed1d 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -1093,6 +1093,7 @@ pub trait OwnedVector { fn pop(&mut self) -> T; fn pop_opt(&mut self) -> Option; fn shift(&mut self) -> T; + fn shift_opt(&mut self) -> Option; fn unshift(&mut self, x: T); fn insert(&mut self, i: uint, x:T); fn remove(&mut self, i: uint) -> T; @@ -1305,20 +1306,26 @@ impl OwnedVector for ~[T] { } /// Removes the first element from a vector and return it + #[inline] fn shift(&mut self) -> T { + self.shift_opt().expect("shift: empty vector") + } + + /// Removes the first element from a vector and return it, or `None` if it is empty + fn shift_opt(&mut self) -> Option { unsafe { - assert!(!self.is_empty()); + let ln = match self.len() { + 0 => return None, + 1 => return self.pop_opt(), + 2 => { + let last = self.pop(); + let first = self.pop_opt(); + self.push(last); + return first; + } + x => x + }; - if self.len() == 1 { return self.pop() } - - if self.len() == 2 { - let last = self.pop(); - let first = self.pop(); - self.push(last); - return first; - } - - let ln = self.len(); let next_ln = self.len() - 1; // Save the last element. We're going to overwrite its position @@ -1354,7 +1361,7 @@ impl OwnedVector for ~[T] { let vp = raw::to_mut_ptr(*self); let vp = ptr::mut_offset(vp, next_ln - 1); - ptr::replace_ptr(vp, work_elt) + Some(ptr::replace_ptr(vp, work_elt)) } } @@ -2763,6 +2770,27 @@ mod tests { assert_eq!([&[1], &[2], &[3]].connect_vec(&0), ~[1, 0, 2, 0, 3]); } + #[test] + fn test_shift() { + let mut x = ~[1, 2, 3]; + assert_eq!(x.shift(), 1); + assert_eq!(&x, &~[2, 3]); + assert_eq!(x.shift(), 2); + assert_eq!(x.shift(), 3); + assert_eq!(x.len(), 0); + } + + #[test] + fn test_shift_opt() { + let mut x = ~[1, 2, 3]; + assert_eq!(x.shift_opt(), Some(1)); + assert_eq!(&x, &~[2, 3]); + assert_eq!(x.shift_opt(), Some(2)); + assert_eq!(x.shift_opt(), Some(3)); + assert_eq!(x.shift_opt(), None); + assert_eq!(x.len(), 0); + } + #[test] fn test_unshift() { let mut x = ~[1, 2, 3]; From 37494d39d38be33a589a1f46dae38fe2ceb9d94f Mon Sep 17 00:00:00 2001 From: Gary Linscott Date: Fri, 5 Jul 2013 19:01:57 -0400 Subject: [PATCH 57/93] Switch json parsing to read_chars for performance Avoids the overhead of read_char for every character. Benchmark reading example.json 10 times from https://code.google.com/p/rapidjson/wiki/Performance Before: 2.55s After: 0.16s Regression testing is already done by isrustfastyet. --- src/libextra/json.rs | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/libextra/json.rs b/src/libextra/json.rs index 71d99479693f..5b9cc338b37b 100644 --- a/src/libextra/json.rs +++ b/src/libextra/json.rs @@ -481,9 +481,13 @@ pub fn to_pretty_str(json: &Json) -> ~str { io::with_str_writer(|wr| to_pretty_writer(wr, json)) } +static BUF_SIZE : uint = 64000; + #[allow(missing_doc)] pub struct Parser { priv rdr: @io::Reader, + priv buf: ~[char], + priv buf_idx: uint, priv ch: char, priv line: uint, priv col: uint, @@ -491,12 +495,16 @@ pub struct Parser { /// Decode a json value from an io::reader pub fn Parser(rdr: @io::Reader) -> Parser { - Parser { + let mut p = Parser { rdr: rdr, - ch: rdr.read_char(), + buf: rdr.read_chars(BUF_SIZE), + buf_idx: 0, + ch: 0 as char, line: 1, - col: 1, - } + col: 0, + }; + p.bump(); + p } impl Parser { @@ -521,13 +529,26 @@ impl Parser { fn eof(&self) -> bool { self.ch == -1 as char } fn bump(&mut self) { - self.ch = self.rdr.read_char(); + if self.eof() { + return; + } + + self.col += 1u; + + if self.buf_idx >= self.buf.len() { + self.buf = self.rdr.read_chars(BUF_SIZE); + if self.buf.len() == 0 { + self.ch = -1 as char; + return; + } + self.buf_idx = 0; + } + self.ch = self.buf[self.buf_idx]; + self.buf_idx += 1; if self.ch == '\n' { self.line += 1u; self.col = 1u; - } else { - self.col += 1u; } } From 5a37cf8a31c4d4eeb1805eb3e90894b8e67d16c8 Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Sat, 6 Jul 2013 05:42:45 +0200 Subject: [PATCH 58/93] deque: Fix grow condition in add_front Without this, it will hit the assert in fn grow after 32 consecutive add_front. --- src/libextra/deque.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libextra/deque.rs b/src/libextra/deque.rs index e89c12e5848d..bc4d365e4488 100644 --- a/src/libextra/deque.rs +++ b/src/libextra/deque.rs @@ -107,7 +107,7 @@ impl Deque { if self.lo == 0u { self.lo = self.elts.len() - 1u; } else { self.lo -= 1u; } - if self.lo == self.hi { + if self.nelts == self.elts.len() { self.elts = grow(self.nelts, oldlo, self.elts); self.lo = self.elts.len() - 1u; self.hi = self.nelts; From 81933edf92afda59ea41ec3692ab43759285b731 Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Sat, 6 Jul 2013 05:42:45 +0200 Subject: [PATCH 59/93] deque: Add tests and bench tests Add a test that excercises deque growing. Add bench tests for grow, new, add_back, add_front, to expose how slow these functions are. --- src/libextra/deque.rs | 56 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/libextra/deque.rs b/src/libextra/deque.rs index bc4d365e4488..a07d9e6fd22a 100644 --- a/src/libextra/deque.rs +++ b/src/libextra/deque.rs @@ -256,6 +256,7 @@ mod tests { use std::cmp::Eq; use std::kinds::Copy; use std::int; + use extra::test; #[test] fn test_simple() { @@ -369,6 +370,61 @@ mod tests { assert_eq!(copy *deq.get(3), copy d); } + #[test] + fn test_add_front_grow() { + let mut deq = Deque::new(); + for int::range(0, 66) |i| { + deq.add_front(i); + } + assert_eq!(deq.len(), 66); + + for int::range(0, 66) |i| { + assert_eq!(*deq.get(i), 65 - i); + } + + let mut deq = Deque::new(); + for int::range(0, 66) |i| { + deq.add_back(i); + } + + for int::range(0, 66) |i| { + assert_eq!(*deq.get(i), i); + } + } + + #[bench] + fn bench_new(b: &mut test::BenchHarness) { + do b.iter { + let _ = Deque::new::(); + } + } + + #[bench] + fn bench_add_back(b: &mut test::BenchHarness) { + let mut deq = Deque::new(); + do b.iter { + deq.add_back(0); + } + } + + #[bench] + fn bench_add_front(b: &mut test::BenchHarness) { + let mut deq = Deque::new(); + do b.iter { + deq.add_front(0); + } + } + + #[bench] + fn bench_grow(b: &mut test::BenchHarness) { + let mut deq = Deque::new(); + do b.iter { + for 65.times { + deq.add_front(1); + } + } + } + #[deriving(Eq)] enum Taggy { One(int), Two(int, int), Three(int, int, int), } From 40ce0b7d76fe39c58e4bdf119af33c4d24950077 Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Sat, 6 Jul 2013 05:42:45 +0200 Subject: [PATCH 60/93] deque: Speed up deque growth by a lot Fix some issues with the deque being very slow, keep the same vec around instead of constructing a new. Move as few elements as possible, so the self.lo point is not moved after grow. [o o o o o|o o o] hi...^ ^.... lo grows to [. . . . .|o o o o o o o o|. . .] ^.. lo ^.. hi If the deque is append-only, it will result in moving no elements on grow. If the deque is prepend-only, all will be moved each time. The bench tests added show big improvements: Timed using `rust build -O --test extra.rs && ./extra --bench deque` Old version: test deque::tests::bench_add_back ... bench: 4976 ns/iter (+/- 9) test deque::tests::bench_add_front ... bench: 4108 ns/iter (+/- 18) test deque::tests::bench_grow ... bench: 416964 ns/iter (+/- 4197) test deque::tests::bench_new ... bench: 408 ns/iter (+/- 12) With this commit: test deque::tests::bench_add_back ... bench: 12 ns/iter (+/- 0) test deque::tests::bench_add_front ... bench: 16 ns/iter (+/- 0) test deque::tests::bench_grow ... bench: 1515 ns/iter (+/- 30) test deque::tests::bench_new ... bench: 419 ns/iter (+/- 3) --- src/libextra/deque.rs | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/libextra/deque.rs b/src/libextra/deque.rs index a07d9e6fd22a..02d3e81148f1 100644 --- a/src/libextra/deque.rs +++ b/src/libextra/deque.rs @@ -11,7 +11,6 @@ //! A double-ended queue implemented as a circular buffer use std::uint; -use std::util::replace; use std::vec; use std::cast::transmute; @@ -103,15 +102,13 @@ impl Deque { /// Prepend an element to the deque pub fn add_front(&mut self, t: T) { - let oldlo = self.lo; + if self.nelts == self.elts.len() { + grow(self.nelts, self.lo, &mut self.elts); + self.hi = self.lo + self.nelts; + } if self.lo == 0u { self.lo = self.elts.len() - 1u; } else { self.lo -= 1u; } - if self.nelts == self.elts.len() { - self.elts = grow(self.nelts, oldlo, self.elts); - self.lo = self.elts.len() - 1u; - self.hi = self.nelts; - } self.elts[self.lo] = Some(t); self.nelts += 1u; } @@ -119,12 +116,14 @@ impl Deque { /// Append an element to the deque pub fn add_back(&mut self, t: T) { if self.lo == self.hi && self.nelts != 0u { - self.elts = grow(self.nelts, self.lo, self.elts); - self.lo = 0u; - self.hi = self.nelts; + grow(self.nelts, self.lo, &mut self.elts); + self.hi = self.lo + self.nelts; } self.elts[self.hi] = Some(t); - self.hi = (self.hi + 1u) % self.elts.len(); + self.hi += 1; + if self.hi == self.elts.len() { + self.hi = 0; + } self.nelts += 1u; } @@ -235,15 +234,19 @@ iterator!{impl DequeMutRevIterator -> &'self mut T, -1} /// Grow is only called on full elts, so nelts is also len(elts), unlike /// elsewhere. -fn grow(nelts: uint, lo: uint, elts: &mut [Option]) -> ~[Option] { +fn grow(nelts: uint, lo: uint, elts: &mut ~[Option]) { assert_eq!(nelts, elts.len()); - let mut rv = ~[]; + let newlen = elts.capacity() * 2; + elts.reserve(newlen); - do rv.grow_fn(nelts + 1) |i| { - replace(&mut elts[(lo + i) % nelts], None) + /* fill with None */ + for uint::range(elts.len(), elts.capacity()) |_| { + elts.push(None); + } + /* move the former wraparound to the new half */ + for uint::range(0, lo) |i| { + elts.swap(i, nelts + i); } - - rv } fn get<'r, T>(elts: &'r [Option], i: uint) -> &'r T { From 08dc72f5d54d3385d2a772b0ce2c92459ff25bfd Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Sat, 6 Jul 2013 05:42:45 +0200 Subject: [PATCH 61/93] deque: Implement FromIterator So that deque can be used with IteratorUtil::collect() --- src/libextra/deque.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/libextra/deque.rs b/src/libextra/deque.rs index 02d3e81148f1..3710f089e2f7 100644 --- a/src/libextra/deque.rs +++ b/src/libextra/deque.rs @@ -13,6 +13,7 @@ use std::uint; use std::vec; use std::cast::transmute; +use std::iterator::FromIterator; static INITIAL_CAPACITY: uint = 32u; // 2^5 @@ -253,6 +254,16 @@ fn get<'r, T>(elts: &'r [Option], i: uint) -> &'r T { match elts[i] { Some(ref t) => t, _ => fail!() } } +impl> FromIterator for Deque { + fn from_iterator(iterator: &mut T) -> Deque { + let mut deq = Deque::new(); + for iterator.advance |elt| { + deq.add_back(elt); + } + deq + } +} + #[cfg(test)] mod tests { use super::*; @@ -545,4 +556,20 @@ mod tests { } assert_eq!(d.rev_iter().collect::<~[&int]>(), ~[&4,&3,&2,&1,&0,&6,&7,&8]); } + + #[test] + fn test_from_iterator() { + use std::iterator; + let v = ~[1,2,3,4,5,6,7]; + let deq: Deque = v.iter().transform(|&x| x).collect(); + let u: ~[int] = deq.iter().transform(|&x| x).collect(); + assert_eq!(u, v); + + let mut seq = iterator::Counter::new(0u, 2).take_(256); + let deq: Deque = seq.collect(); + for deq.iter().enumerate().advance |(i, &x)| { + assert_eq!(2*i, x); + } + assert_eq!(deq.len(), 256); + } } From 5d72f3f296b7815a4e8ec7b6b3e03bd7a4ed47ba Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Sat, 6 Jul 2013 05:42:45 +0200 Subject: [PATCH 62/93] deque: Remove rendundant field hi The deque is determined by vec self.elts.len(), self.nelts, and self.lo, and self.hi is calculated from these. self.hi is just the raw index of element number `self.nelts` --- src/libextra/deque.rs | 48 +++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/src/libextra/deque.rs b/src/libextra/deque.rs index 3710f089e2f7..04941e9886e2 100644 --- a/src/libextra/deque.rs +++ b/src/libextra/deque.rs @@ -21,7 +21,6 @@ static INITIAL_CAPACITY: uint = 32u; // 2^5 pub struct Deque { priv nelts: uint, priv lo: uint, - priv hi: uint, priv elts: ~[Option] } @@ -39,26 +38,31 @@ impl Mutable for Deque { for self.elts.mut_iter().advance |x| { *x = None } self.nelts = 0; self.lo = 0; - self.hi = 0; } } impl Deque { /// Create an empty Deque pub fn new() -> Deque { - Deque{nelts: 0, lo: 0, hi: 0, + Deque{nelts: 0, lo: 0, elts: vec::from_fn(INITIAL_CAPACITY, |_| None)} } /// Return a reference to the first element in the deque /// /// Fails if the deque is empty - pub fn peek_front<'a>(&'a self) -> &'a T { get(self.elts, self.lo) } + pub fn peek_front<'a>(&'a self) -> &'a T { get(self.elts, self.raw_index(0)) } /// Return a reference to the last element in the deque /// /// Fails if the deque is empty - pub fn peek_back<'a>(&'a self) -> &'a T { get(self.elts, self.hi - 1u) } + pub fn peek_back<'a>(&'a self) -> &'a T { + if self.nelts > 0 { + get(self.elts, self.raw_index(self.nelts - 1)) + } else { + fail!("peek_back: empty deque"); + } + } /// Retrieve an element in the deque by index /// @@ -88,24 +92,28 @@ impl Deque { result } + /// Return index in underlying vec for element index + fn raw_index(&self, idx: uint) -> uint { + if self.lo >= self.elts.len() - idx { + (self.lo + idx) - self.elts.len() + } else { + (self.lo + idx) + } + } + /// Remove and return the last element in the deque /// /// Fails if the deque is empty pub fn pop_back(&mut self) -> T { - if self.hi == 0u { - self.hi = self.elts.len() - 1u; - } else { self.hi -= 1u; } - let result = self.elts[self.hi].swap_unwrap(); - self.elts[self.hi] = None; - self.nelts -= 1u; - result + self.nelts -= 1; + let hi = self.raw_index(self.nelts); + self.elts[hi].swap_unwrap() } /// Prepend an element to the deque pub fn add_front(&mut self, t: T) { if self.nelts == self.elts.len() { grow(self.nelts, self.lo, &mut self.elts); - self.hi = self.lo + self.nelts; } if self.lo == 0u { self.lo = self.elts.len() - 1u; @@ -116,15 +124,11 @@ impl Deque { /// Append an element to the deque pub fn add_back(&mut self, t: T) { - if self.lo == self.hi && self.nelts != 0u { + if self.nelts == self.elts.len() { grow(self.nelts, self.lo, &mut self.elts); - self.hi = self.lo + self.nelts; - } - self.elts[self.hi] = Some(t); - self.hi += 1; - if self.hi == self.elts.len() { - self.hi = 0; } + let hi = self.raw_index(self.nelts); + self.elts[hi] = Some(t); self.nelts += 1u; } @@ -165,12 +169,12 @@ impl Deque { /// Back-to-front iterator. pub fn rev_iter<'a>(&'a self) -> DequeRevIterator<'a, T> { - DequeRevIterator { idx: self.hi - 1u, nelts: self.nelts, used: 0, vec: self.elts } + DequeRevIterator { idx: self.raw_index(self.nelts-1), nelts: self.nelts, used: 0, vec: self.elts } } /// Back-to-front iterator which returns mutable values. pub fn mut_rev_iter<'a>(&'a mut self) -> DequeMutRevIterator<'a, T> { - DequeMutRevIterator { idx: self.hi - 1u, nelts: self.nelts, used: 0, vec: self.elts } + DequeMutRevIterator { idx: self.raw_index(self.nelts-1), nelts: self.nelts, used: 0, vec: self.elts } } } From f88d532734dbddecf81bc1d0ce51d30cb9fc9731 Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Sat, 6 Jul 2013 05:42:45 +0200 Subject: [PATCH 63/93] deque: Add tests for mut_iter and mut_rev_iter --- src/libextra/deque.rs | 52 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/src/libextra/deque.rs b/src/libextra/deque.rs index 04941e9886e2..bd7b9d5b51d1 100644 --- a/src/libextra/deque.rs +++ b/src/libextra/deque.rs @@ -273,7 +273,7 @@ mod tests { use super::*; use std::cmp::Eq; use std::kinds::Copy; - use std::int; + use std::{int, uint}; use extra::test; #[test] @@ -536,6 +536,8 @@ mod tests { #[test] fn test_iter() { let mut d = Deque::new(); + assert_eq!(d.iter().next(), None); + for int::range(0,5) |i| { d.add_back(i); } @@ -550,6 +552,8 @@ mod tests { #[test] fn test_rev_iter() { let mut d = Deque::new(); + assert_eq!(d.rev_iter().next(), None); + for int::range(0,5) |i| { d.add_back(i); } @@ -561,6 +565,52 @@ mod tests { assert_eq!(d.rev_iter().collect::<~[&int]>(), ~[&4,&3,&2,&1,&0,&6,&7,&8]); } + #[test] + fn test_mut_iter() { + let mut d = Deque::new(); + assert!(d.mut_iter().next().is_none()); + + for uint::range(0,3) |i| { + d.add_front(i); + } + + for d.mut_iter().enumerate().advance |(i, elt)| { + assert_eq!(*elt, 2 - i); + *elt = i; + } + + { + let mut it = d.mut_iter(); + assert_eq!(*it.next().unwrap(), 0); + assert_eq!(*it.next().unwrap(), 1); + assert_eq!(*it.next().unwrap(), 2); + assert!(it.next().is_none()); + } + } + + #[test] + fn test_mut_rev_iter() { + let mut d = Deque::new(); + assert!(d.mut_rev_iter().next().is_none()); + + for uint::range(0,3) |i| { + d.add_front(i); + } + + for d.mut_rev_iter().enumerate().advance |(i, elt)| { + assert_eq!(*elt, i); + *elt = i; + } + + { + let mut it = d.mut_rev_iter(); + assert_eq!(*it.next().unwrap(), 0); + assert_eq!(*it.next().unwrap(), 1); + assert_eq!(*it.next().unwrap(), 2); + assert!(it.next().is_none()); + } + } + #[test] fn test_from_iterator() { use std::iterator; From 75015c36f9fa6d0958874c1a448d6d67056145ae Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Sat, 6 Jul 2013 05:42:45 +0200 Subject: [PATCH 64/93] deque: Change iterators to use the same index calculation as Deque The previous implementation of reverse iterators used modulus (%) of negative indices, which did work but was fragile due to dependency on the divisor. --- src/libextra/deque.rs | 78 +++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/src/libextra/deque.rs b/src/libextra/deque.rs index bd7b9d5b51d1..e8f8a31d7be0 100644 --- a/src/libextra/deque.rs +++ b/src/libextra/deque.rs @@ -12,7 +12,6 @@ use std::uint; use std::vec; -use std::cast::transmute; use std::iterator::FromIterator; static INITIAL_CAPACITY: uint = 32u; // 2^5 @@ -92,13 +91,9 @@ impl Deque { result } - /// Return index in underlying vec for element index + /// Return index in underlying vec for a given logical element index fn raw_index(&self, idx: uint) -> uint { - if self.lo >= self.elts.len() - idx { - (self.lo + idx) - self.elts.len() - } else { - (self.lo + idx) - } + raw_index(self.lo, self.elts.len(), idx) } /// Remove and return the last element in the deque @@ -159,42 +154,39 @@ impl Deque { /// Front-to-back iterator. pub fn iter<'a>(&'a self) -> DequeIterator<'a, T> { - DequeIterator { idx: self.lo, nelts: self.nelts, used: 0, vec: self.elts } + DequeIterator{index: 0, nelts: self.nelts, elts: self.elts, lo: self.lo} } /// Front-to-back iterator which returns mutable values. pub fn mut_iter<'a>(&'a mut self) -> DequeMutIterator<'a, T> { - DequeMutIterator { idx: self.lo, nelts: self.nelts, used: 0, vec: self.elts } + DequeMutIterator{index: 0, nelts: self.nelts, elts: self.elts, lo: self.lo} } /// Back-to-front iterator. pub fn rev_iter<'a>(&'a self) -> DequeRevIterator<'a, T> { - DequeRevIterator { idx: self.raw_index(self.nelts-1), nelts: self.nelts, used: 0, vec: self.elts } + DequeRevIterator{index: self.nelts-1, nelts: self.nelts, elts: self.elts, + lo: self.lo} } /// Back-to-front iterator which returns mutable values. pub fn mut_rev_iter<'a>(&'a mut self) -> DequeMutRevIterator<'a, T> { - DequeMutRevIterator { idx: self.raw_index(self.nelts-1), nelts: self.nelts, used: 0, vec: self.elts } + DequeMutRevIterator{index: self.nelts-1, nelts: self.nelts, elts: self.elts, + lo: self.lo} } } macro_rules! iterator { - (impl $name:ident -> $elem:ty, $step:expr) => { + (impl $name:ident -> $elem:ty, $getter:ident, $step:expr) => { impl<'self, T> Iterator<$elem> for $name<'self, T> { #[inline] fn next(&mut self) -> Option<$elem> { - if self.used >= self.nelts { + if self.nelts == 0 { return None; } - let ret = unsafe { - match self.vec[self.idx % self.vec.len()] { - Some(ref e) => Some(transmute(e)), - None => None - } - }; - self.idx += $step; - self.used += 1; - ret + let raw_index = raw_index(self.lo, self.elts.len(), self.index); + self.index += $step; + self.nelts -= 1; + Some(self.elts[raw_index]. $getter ()) } } } @@ -202,40 +194,39 @@ macro_rules! iterator { /// Deque iterator pub struct DequeIterator<'self, T> { - priv idx: uint, + priv lo: uint, priv nelts: uint, - priv used: uint, - priv vec: &'self [Option] + priv index: uint, + priv elts: &'self [Option], } -iterator!{impl DequeIterator -> &'self T, 1} +iterator!{impl DequeIterator -> &'self T, get_ref, 1} /// Deque reverse iterator pub struct DequeRevIterator<'self, T> { - priv idx: uint, + priv lo: uint, priv nelts: uint, - priv used: uint, - priv vec: &'self [Option] + priv index: uint, + priv elts: &'self [Option], } -iterator!{impl DequeRevIterator -> &'self T, -1} +iterator!{impl DequeRevIterator -> &'self T, get_ref, -1} /// Deque mutable iterator pub struct DequeMutIterator<'self, T> { - priv idx: uint, + priv lo: uint, priv nelts: uint, - priv used: uint, - priv vec: &'self mut [Option] - + priv index: uint, + priv elts: &'self mut [Option], } -iterator!{impl DequeMutIterator -> &'self mut T, 1} +iterator!{impl DequeMutIterator -> &'self mut T, get_mut_ref, 1} /// Deque mutable reverse iterator pub struct DequeMutRevIterator<'self, T> { - priv idx: uint, + priv lo: uint, priv nelts: uint, - priv used: uint, - priv vec: &'self mut [Option] + priv index: uint, + priv elts: &'self mut [Option], } -iterator!{impl DequeMutRevIterator -> &'self mut T, -1} +iterator!{impl DequeMutRevIterator -> &'self mut T, get_mut_ref, -1} /// Grow is only called on full elts, so nelts is also len(elts), unlike /// elsewhere. @@ -258,6 +249,15 @@ fn get<'r, T>(elts: &'r [Option], i: uint) -> &'r T { match elts[i] { Some(ref t) => t, _ => fail!() } } +/// Return index in underlying vec for a given logical element index +fn raw_index(lo: uint, len: uint, index: uint) -> uint { + if lo >= len - index { + lo + index - len + } else { + lo + index + } +} + impl> FromIterator for Deque { fn from_iterator(iterator: &mut T) -> Deque { let mut deq = Deque::new(); From 8a3267672c43e7cc116e588dd21998d14fc21ba4 Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Sat, 6 Jul 2013 05:42:45 +0200 Subject: [PATCH 65/93] deque: Move the shorter part when growing The deque is split at the marker lo, or logical index 0. Move the shortest part (split by lo) when growing. This way add_front is just as fast as add_back, on average. --- src/libextra/deque.rs | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/libextra/deque.rs b/src/libextra/deque.rs index e8f8a31d7be0..3dfc90002d3c 100644 --- a/src/libextra/deque.rs +++ b/src/libextra/deque.rs @@ -108,7 +108,7 @@ impl Deque { /// Prepend an element to the deque pub fn add_front(&mut self, t: T) { if self.nelts == self.elts.len() { - grow(self.nelts, self.lo, &mut self.elts); + grow(self.nelts, &mut self.lo, &mut self.elts); } if self.lo == 0u { self.lo = self.elts.len() - 1u; @@ -120,7 +120,7 @@ impl Deque { /// Append an element to the deque pub fn add_back(&mut self, t: T) { if self.nelts == self.elts.len() { - grow(self.nelts, self.lo, &mut self.elts); + grow(self.nelts, &mut self.lo, &mut self.elts); } let hi = self.raw_index(self.nelts); self.elts[hi] = Some(t); @@ -230,18 +230,36 @@ iterator!{impl DequeMutRevIterator -> &'self mut T, get_mut_ref, -1} /// Grow is only called on full elts, so nelts is also len(elts), unlike /// elsewhere. -fn grow(nelts: uint, lo: uint, elts: &mut ~[Option]) { +fn grow(nelts: uint, loptr: &mut uint, elts: &mut ~[Option]) { assert_eq!(nelts, elts.len()); - let newlen = elts.capacity() * 2; + let lo = *loptr; + let newlen = nelts * 2; elts.reserve(newlen); /* fill with None */ for uint::range(elts.len(), elts.capacity()) |_| { elts.push(None); } - /* move the former wraparound to the new half */ - for uint::range(0, lo) |i| { - elts.swap(i, nelts + i); + + /* + Move the shortest half into the newly reserved area. + lo ---->| + nelts ----------->| + [o o o|o o o o o] + A [. . .|o o o o o o o o|. . . . .] + B [o o o|. . . . . . . .|o o o o o] + */ + + assert!(newlen - nelts/2 >= nelts); + if lo <= (nelts - lo) { // A + for uint::range(0, lo) |i| { + elts.swap(i, nelts + i); + } + } else { // B + for uint::range(lo, nelts) |i| { + elts.swap(i, newlen - nelts + i); + } + *loptr += newlen - nelts; } } From 0ff5c17cbbef0aedfa2eb1142cbf7a87abfd1d05 Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Sat, 6 Jul 2013 05:42:45 +0200 Subject: [PATCH 66/93] deque: Implement Deque::with_capacity. Lower initial capacity to 8. We need a reasonably small initial capacity to make Deques faster for the common case. --- src/libextra/deque.rs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/libextra/deque.rs b/src/libextra/deque.rs index 3dfc90002d3c..c537167946c7 100644 --- a/src/libextra/deque.rs +++ b/src/libextra/deque.rs @@ -14,7 +14,8 @@ use std::uint; use std::vec; use std::iterator::FromIterator; -static INITIAL_CAPACITY: uint = 32u; // 2^5 +static INITIAL_CAPACITY: uint = 8u; // 2^3 +static MINIMUM_CAPACITY: uint = 2u; #[allow(missing_doc)] pub struct Deque { @@ -43,8 +44,13 @@ impl Mutable for Deque { impl Deque { /// Create an empty Deque pub fn new() -> Deque { + Deque::with_capacity(INITIAL_CAPACITY) + } + + /// Create an empty Deque with space for at least `n` elements. + pub fn with_capacity(n: uint) -> Deque { Deque{nelts: 0, lo: 0, - elts: vec::from_fn(INITIAL_CAPACITY, |_| None)} + elts: vec::from_fn(uint::max(MINIMUM_CAPACITY, n), |_| None)} } /// Return a reference to the first element in the deque @@ -527,6 +533,16 @@ mod tests { } + #[test] + fn test_with_capacity() { + let mut d = Deque::with_capacity(0); + d.add_back(1); + assert_eq!(d.len(), 1); + let mut d = Deque::with_capacity(50); + d.add_back(1); + assert_eq!(d.len(), 1); + } + #[test] fn test_reserve() { let mut d = Deque::new(); From 07e2775dff0643f0f8f66f5ecf92ab7ee163bce4 Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Sat, 6 Jul 2013 05:42:46 +0200 Subject: [PATCH 67/93] deque: Remove obsolete methods .each() and .eachi() --- src/libextra/deque.rs | 29 ----------------------------- src/libextra/serialize.rs | 2 +- 2 files changed, 1 insertion(+), 30 deletions(-) diff --git a/src/libextra/deque.rs b/src/libextra/deque.rs index c537167946c7..9e19d8746a40 100644 --- a/src/libextra/deque.rs +++ b/src/libextra/deque.rs @@ -77,16 +77,6 @@ impl Deque { get(self.elts, idx) } - /// Iterate over the elements in the deque - pub fn each(&self, f: &fn(&T) -> bool) -> bool { - self.eachi(|_i, e| f(e)) - } - - /// Iterate over the elements in the deque by index - pub fn eachi(&self, f: &fn(uint, &T) -> bool) -> bool { - uint::range(0, self.nelts, |i| f(i, self.get(i as int))) - } - /// Remove and return the first element in the deque /// /// Fails if the deque is empty @@ -514,25 +504,6 @@ mod tests { test_parameterized::(reccy1, reccy2, reccy3, reccy4); } - #[test] - fn test_eachi() { - let mut deq = Deque::new(); - deq.add_back(1); - deq.add_back(2); - deq.add_back(3); - - for deq.eachi |i, e| { - assert_eq!(*e, i + 1); - } - - deq.pop_front(); - - for deq.eachi |i, e| { - assert_eq!(*e, i + 2); - } - - } - #[test] fn test_with_capacity() { let mut d = Deque::with_capacity(0); diff --git a/src/libextra/serialize.rs b/src/libextra/serialize.rs index 66b178f49f7f..b1383948bf72 100644 --- a/src/libextra/serialize.rs +++ b/src/libextra/serialize.rs @@ -682,7 +682,7 @@ impl< > Encodable for Deque { fn encode(&self, s: &mut S) { do s.emit_seq(self.len()) |s| { - for self.eachi |i, e| { + for self.iter().enumerate().advance |(i, e)| { s.emit_seq_elt(i, |s| e.encode(s)); } } From 52949fbf1876ecd03303006c534a74c5e29bc90d Mon Sep 17 00:00:00 2001 From: Gary Linscott Date: Sat, 6 Jul 2013 01:54:29 -0400 Subject: [PATCH 68/93] Faster check for ascii-space Since ' ' is by far one of the most common characters, it is worthwhile to put it first, and short-circuit the rest of the function. On the same JSON benchmark, as the json_perf improvement, reading example.json 10 times from https://code.google.com/p/rapidjson/wiki/Performance. Before: 0.16s After: 0.11s --- src/libstd/char.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libstd/char.rs b/src/libstd/char.rs index 6a9555f4efcd..47473c2faba6 100644 --- a/src/libstd/char.rs +++ b/src/libstd/char.rs @@ -82,7 +82,8 @@ pub fn is_uppercase(c: char) -> bool { general_category::Lu(c) } /// #[inline] pub fn is_whitespace(c: char) -> bool { - ('\x09' <= c && c <= '\x0d') + c == ' ' + || ('\x09' <= c && c <= '\x0d') || general_category::Zs(c) || general_category::Zl(c) || general_category::Zp(c) From f1159446ba85fbf6e1ab9ae1f412abddc195142d Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Sat, 6 Jul 2013 02:19:37 -0700 Subject: [PATCH 69/93] Update tests.mk disable rusti tests, nothing's landing --- mk/tests.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mk/tests.mk b/mk/tests.mk index 35d567ef771b..9a991c151978 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -15,7 +15,7 @@ # The names of crates that must be tested TEST_TARGET_CRATES = std extra -TEST_HOST_CRATES = syntax rustc rustdoc rusti rust rustpkg +TEST_HOST_CRATES = syntax rustc rustdoc rust rustpkg TEST_CRATES = $(TEST_TARGET_CRATES) $(TEST_HOST_CRATES) # Markdown files under doc/ that should have their code extracted and run From 10c7698d4b43aa9bd9b30df5e0769189d3a83110 Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Sat, 6 Jul 2013 15:27:32 +0200 Subject: [PATCH 70/93] deque: Implement Clone and Eq for Deque --- src/libextra/deque.rs | 49 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/libextra/deque.rs b/src/libextra/deque.rs index 9e19d8746a40..36ebf295aaba 100644 --- a/src/libextra/deque.rs +++ b/src/libextra/deque.rs @@ -18,6 +18,7 @@ static INITIAL_CAPACITY: uint = 8u; // 2^3 static MINIMUM_CAPACITY: uint = 2u; #[allow(missing_doc)] +#[deriving(Clone)] pub struct Deque { priv nelts: uint, priv lo: uint, @@ -272,6 +273,16 @@ fn raw_index(lo: uint, len: uint, index: uint) -> uint { } } +impl Eq for Deque { + fn eq(&self, other: &Deque) -> bool { + self.nelts == other.nelts && + self.iter().zip(other.iter()).all(|(a, b)| a.eq(b)) + } + fn ne(&self, other: &Deque) -> bool { + !self.eq(other) + } +} + impl> FromIterator for Deque { fn from_iterator(iterator: &mut T) -> Deque { let mut deq = Deque::new(); @@ -631,4 +642,42 @@ mod tests { } assert_eq!(deq.len(), 256); } + + #[test] + fn test_clone() { + let mut d = Deque::new(); + d.add_front(17); + d.add_front(42); + d.add_back(137); + d.add_back(137); + assert_eq!(d.len(), 4u); + let mut e = d.clone(); + assert_eq!(e.len(), 4u); + while !d.is_empty() { + assert_eq!(d.pop_back(), e.pop_back()); + } + assert_eq!(d.len(), 0u); + assert_eq!(e.len(), 0u); + } + + #[test] + fn test_eq() { + let mut d = Deque::new(); + assert_eq!(&d, &Deque::with_capacity(0)); + d.add_front(137); + d.add_front(17); + d.add_front(42); + d.add_back(137); + let mut e = Deque::with_capacity(0); + e.add_back(42); + e.add_back(17); + e.add_back(137); + e.add_back(137); + assert_eq!(&e, &d); + e.pop_back(); + e.add_back(0); + assert!(e != d); + e.clear(); + assert_eq!(e, Deque::new()); + } } From 01833de7ea4c3d73351277b52f841d42d7d2dbb8 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 6 Jul 2013 17:06:30 -0400 Subject: [PATCH 71/93] remove extra::rope It's broken/unmaintained and needs to be rewritten to avoid managed pointers and needless copies. A full rewrite is necessary and the API will need to be redone so it's not worth keeping this around. Closes #2236, #2744 --- src/libextra/extra.rs | 1 - src/libextra/rope.rs | 1442 ----------------------------------------- src/libstd/str.rs | 3 +- 3 files changed, 1 insertion(+), 1445 deletions(-) delete mode 100644 src/libextra/rope.rs diff --git a/src/libextra/extra.rs b/src/libextra/extra.rs index 50c57b28d223..c4f72d10a8ae 100644 --- a/src/libextra/extra.rs +++ b/src/libextra/extra.rs @@ -74,7 +74,6 @@ pub mod deque; pub mod fun_treemap; pub mod list; pub mod priority_queue; -pub mod rope; pub mod smallintmap; pub mod sort; diff --git a/src/libextra/rope.rs b/src/libextra/rope.rs deleted file mode 100644 index dd3f08917fd4..000000000000 --- a/src/libextra/rope.rs +++ /dev/null @@ -1,1442 +0,0 @@ -// Copyright 2012 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -/*! - * High-level text containers. - * - * Ropes are a high-level representation of text that offers - * much better performance than strings for common operations, - * and generally reduce memory allocations and copies, while only - * entailing a small degradation of less common operations. - * - * More precisely, where a string is represented as a memory buffer, - * a rope is a tree structure whose leaves are slices of immutable - * strings. Therefore, concatenation, appending, prepending, substrings, - * etc. are operations that require only trivial tree manipulation, - * generally without having to copy memory. In addition, the tree - * structure of ropes makes them suitable as a form of index to speed-up - * access to Unicode characters by index in long chunks of text. - * - * The following operations are algorithmically faster in ropes: - * - * * extracting a subrope is logarithmic (linear in strings); - * * appending/prepending is near-constant time (linear in strings); - * * concatenation is near-constant time (linear in strings); - * * char length is constant-time (linear in strings); - * * access to a character by index is logarithmic (linear in strings); - */ - -#[allow(missing_doc)]; - - -use std::uint; -use std::vec; -use std::str; - -/// The type of ropes. -pub type Rope = node::Root; - -/* - Section: Creating a rope - */ - -/// Create an empty rope -pub fn empty() -> Rope { - return node::Empty; -} - -/** - * Adopt a string as a rope. - * - * # Arguments - * - * * str - A valid string. - * - * # Return value - * - * A rope representing the same string as `str`. Depending of the length - * of `str`, this rope may be empty, flat or complex. - * - * # Performance notes - * - * * this operation does not copy the string; - * * the function runs in linear time. - */ -pub fn of_str(str: @~str) -> Rope { - return of_substr(str, 0u, str.len()); -} - -/** - * As `of_str` but for a substring. - * - * # Arguments - * * byte_offset - The offset of `str` at which the rope starts. - * * byte_len - The number of bytes of `str` to use. - * - * # Return value - * - * A rope representing the same string as `str.slice(byte_offset, - * byte_offset + byte_len)`. Depending on `byte_len`, this rope may - * be empty, flat or complex. - * - * # Performance note - * - * This operation does not copy the substring. - * - * # Safety notes - * - * * this function does _not_ check the validity of the substring; - * * this function fails if `byte_offset` or `byte_len` do not match `str`. - */ -pub fn of_substr(str: @~str, byte_offset: uint, byte_len: uint) -> Rope { - if byte_len == 0u { return node::Empty; } - if byte_offset + byte_len > str.len() { fail!(); } - return node::Content(node::of_substr(str, byte_offset, byte_len)); -} - -/* -Section: Adding things to a rope - */ - -/** - * Add one char to the end of the rope - * - * # Performance note - * - * * this function executes in near-constant time - */ -pub fn append_char(rope: Rope, char: char) -> Rope { - return append_str(rope, @str::from_chars([char])); -} - -/** - * Add one string to the end of the rope - * - * # Performance note - * - * * this function executes in near-linear time - */ -pub fn append_str(rope: Rope, str: @~str) -> Rope { - return append_rope(rope, of_str(str)) -} - -/** - * Add one char to the beginning of the rope - * - * # Performance note - * * this function executes in near-constant time - */ -pub fn prepend_char(rope: Rope, char: char) -> Rope { - return prepend_str(rope, @str::from_chars([char])); -} - -/** - * Add one string to the beginning of the rope - * - * # Performance note - * * this function executes in near-linear time - */ -pub fn prepend_str(rope: Rope, str: @~str) -> Rope { - return append_rope(of_str(str), rope) -} - -/// Concatenate two ropes -pub fn append_rope(left: Rope, right: Rope) -> Rope { - match (left) { - node::Empty => return right, - node::Content(left_content) => { - match (right) { - node::Empty => return left, - node::Content(right_content) => { - return node::Content(node::concat2(left_content, right_content)); - } - } - } - } -} - -/** - * Concatenate many ropes. - * - * If the ropes are balanced initially and have the same height, the resulting - * rope remains balanced. However, this function does not take any further - * measure to ensure that the result is balanced. - */ -pub fn concat(v: ~[Rope]) -> Rope { - //Copy `v` into a mut vector - let mut len = v.len(); - if len == 0u { return node::Empty; } - let mut ropes = vec::from_elem(len, v[0]); - for uint::range(1u, len) |i| { - ropes[i] = v[i]; - } - - //Merge progresively - while len > 1u { - for uint::range(0u, len/2u) |i| { - ropes[i] = append_rope(ropes[2u*i], ropes[2u*i+1u]); - } - if len%2u != 0u { - ropes[len/2u] = ropes[len - 1u]; - len = len/2u + 1u; - } else { - len = len/2u; - } - } - - //Return final rope - return ropes[0]; -} - - -/* -Section: Keeping ropes healthy - */ - - -/** - * Balance a rope. - * - * # Return value - * - * A copy of the rope in which small nodes have been grouped in memory, - * and with a reduced height. - * - * If you perform numerous rope concatenations, it is generally a good idea - * to rebalance your rope at some point, before using it for other purposes. - */ -pub fn bal(rope:Rope) -> Rope { - match (rope) { - node::Empty => return rope, - node::Content(x) => match (node::bal(x)) { - None => rope, - Some(y) => node::Content(y) - } - } -} - -/* -Section: Transforming ropes - */ - - -/** - * Extract a subrope from a rope. - * - * # Performance note - * - * * on a balanced rope, this operation takes algorithmic time; - * * this operation does not involve any copying - * - * # Safety note - * - * * this function fails if char_offset/char_len do not represent - * valid positions in rope - */ -pub fn sub_chars(rope: Rope, char_offset: uint, char_len: uint) -> Rope { - if char_len == 0u { return node::Empty; } - match (rope) { - node::Empty => fail!(), - node::Content(node) => if char_len > node::char_len(node) { - fail!() - } else { - return node::Content(node::sub_chars(node, char_offset, char_len)) - } - } -} - -/** - * Extract a subrope from a rope. - * - * # Performance note - * - * * on a balanced rope, this operation takes algorithmic time; - * * this operation does not involve any copying - * - * # Safety note - * - * * this function fails if byte_offset/byte_len do not represent - * valid positions in rope - */ -pub fn sub_bytes(rope: Rope, byte_offset: uint, byte_len: uint) -> Rope { - if byte_len == 0u { return node::Empty; } - match (rope) { - node::Empty => fail!(), - node::Content(node) =>if byte_len > node::byte_len(node) { - fail!() - } else { - return node::Content(node::sub_bytes(node, byte_offset, byte_len)) - } - } -} - -/* -Section: Comparing ropes - */ - -/** - * Compare two ropes by Unicode lexicographical order. - * - * This function compares only the contents of the rope, not their structure. - * - * # Return value - * - * A negative value if `left < right`, 0 if eq(left, right) or a positive - * value if `left > right` - */ -pub fn cmp(left: Rope, right: Rope) -> int { - match ((left, right)) { - (node::Empty, node::Empty) => return 0, - (node::Empty, _) => return -1, - (_, node::Empty) => return 1, - (node::Content(a), node::Content(b)) => { - return node::cmp(a, b); - } - } -} - -/** - * Returns `true` if both ropes have the same content (regardless of - * their structure), `false` otherwise - */ -pub fn eq(left: Rope, right: Rope) -> bool { - return cmp(left, right) == 0; -} - -/** - * # Arguments - * - * * left - an arbitrary rope - * * right - an arbitrary rope - * - * # Return value - * - * `true` if `left <= right` in lexicographical order (regardless of their - * structure), `false` otherwise - */ -pub fn le(left: Rope, right: Rope) -> bool { - return cmp(left, right) <= 0; -} - -/** - * # Arguments - * - * * left - an arbitrary rope - * * right - an arbitrary rope - * - * # Return value - * - * `true` if `left < right` in lexicographical order (regardless of their - * structure), `false` otherwise - */ -pub fn lt(left: Rope, right: Rope) -> bool { - return cmp(left, right) < 0; -} - -/** - * # Arguments - * - * * left - an arbitrary rope - * * right - an arbitrary rope - * - * # Return value - * - * `true` if `left >= right` in lexicographical order (regardless of their - * structure), `false` otherwise - */ -pub fn ge(left: Rope, right: Rope) -> bool { - return cmp(left, right) >= 0; -} - -/** - * # Arguments - * - * * left - an arbitrary rope - * * right - an arbitrary rope - * - * # Return value - * - * `true` if `left > right` in lexicographical order (regardless of their - * structure), `false` otherwise - */ -pub fn gt(left: Rope, right: Rope) -> bool { - return cmp(left, right) > 0; -} - -/* -Section: Iterating - */ - -/** - * Loop through a rope, char by char - * - * While other mechanisms are available, this is generally the best manner - * of looping through the contents of a rope char by char. If you prefer a - * loop that iterates through the contents string by string (e.g. to print - * the contents of the rope or output it to the system), however, - * you should rather use `traverse_components`. - * - * # Arguments - * - * * rope - A rope to traverse. It may be empty. - * * it - A block to execute with each consecutive character of the rope. - * Return `true` to continue, `false` to stop. - * - * # Return value - * - * `true` If execution proceeded correctly, `false` if it was interrupted, - * that is if `it` returned `false` at any point. - */ -pub fn loop_chars(rope: Rope, it: &fn(c: char) -> bool) -> bool { - match (rope) { - node::Empty => return true, - node::Content(x) => return node::loop_chars(x, it) - } -} - -/** - * Loop through a rope, char by char, until the end. - * - * # Arguments - * * rope - A rope to traverse. It may be empty - * * it - A block to execute with each consecutive character of the rope. - */ -pub fn iter_chars(rope: Rope, it: &fn(char)) { - do loop_chars(rope) |x| { - it(x); - true - }; -} - -/** - * Loop through a rope, string by string - * - * While other mechanisms are available, this is generally the best manner of - * looping through the contents of a rope string by string, which may be - * useful e.g. to print strings as you see them (without having to copy their - * contents into a new string), to send them to then network, to write them to - * a file, etc.. If you prefer a loop that iterates through the contents - * char by char (e.g. to search for a char), however, you should rather - * use `traverse`. - * - * # Arguments - * - * * rope - A rope to traverse. It may be empty - * * it - A block to execute with each consecutive string component of the - * rope. Return `true` to continue, `false` to stop - * - * # Return value - * - * `true` If execution proceeded correctly, `false` if it was interrupted, - * that is if `it` returned `false` at any point. - */ -pub fn loop_leaves(rope: Rope, it: &fn(node::Leaf) -> bool) -> bool{ - match (rope) { - node::Empty => return true, - node::Content(x) => return node::loop_leaves(x, it) - } -} - -pub mod iterator { - pub mod leaf { - - use rope::{Rope, node}; - - pub fn start(rope: Rope) -> node::leaf_iterator::T { - match (rope) { - node::Empty => return node::leaf_iterator::empty(), - node::Content(x) => return node::leaf_iterator::start(x) - } - } - pub fn next(it: &mut node::leaf_iterator::T) -> Option { - return node::leaf_iterator::next(it); - } - } - pub mod char { - - use rope::{Rope, node}; - - pub fn start(rope: Rope) -> node::char_iterator::T { - match (rope) { - node::Empty => return node::char_iterator::empty(), - node::Content(x) => return node::char_iterator::start(x) - } - } - pub fn next(it: &mut node::char_iterator::T) -> Option { - return node::char_iterator::next(it) - } - } -} - -/* - Section: Rope properties - */ - -/** - * Returns the height of the rope. - * - * The height of the rope is a bound on the number of operations which - * must be performed during a character access before finding the leaf in - * which a character is contained. - * - * # Performance note - * - * Constant time. - */ -pub fn height(rope: Rope) -> uint { - match (rope) { - node::Empty => return 0u, - node::Content(x) => return node::height(x) - } -} - - - -/** - * The number of character in the rope - * - * # Performance note - * - * Constant time. - */ -pub fn char_len(rope: Rope) -> uint { - match (rope) { - node::Empty => return 0u, - node::Content(x) => return node::char_len(x) - } -} - -/** - * The number of bytes in the rope - * - * # Performance note - * - * Constant time. - */ -pub fn byte_len(rope: Rope) -> uint { - match (rope) { - node::Empty => return 0u, - node::Content(x) => return node::byte_len(x) - } -} - -/** - * The character at position `pos` - * - * # Arguments - * - * * pos - A position in the rope - * - * # Safety notes - * - * The function will fail if `pos` is not a valid position in the rope. - * - * # Performance note - * - * This function executes in a time proportional to the height of the - * rope + the (bounded) length of the largest leaf. - */ -pub fn char_at(rope: Rope, pos: uint) -> char { - match (rope) { - node::Empty => fail!(), - node::Content(x) => return node::char_at(x, pos) - } -} - - -/* - Section: Implementation -*/ -pub mod node { - - use rope::node; - - use std::cast; - use std::uint; - use std::vec; - - /// Implementation of type `rope` - pub enum Root { - /// An empty rope - Empty, - /// A non-empty rope - Content(@Node), - } - - /** - * A text component in a rope. - * - * This is actually a slice in a rope, so as to ensure maximal sharing. - * - * # Fields - * - * * byte_offset = The number of bytes skipped in `content` - * * byte_len - The number of bytes of `content` to use - * * char_len - The number of chars in the leaf. - * * content - Contents of the leaf. - * - * Note that we can have `char_len < content.char_len()`, if - * this leaf is only a subset of the string. Also note that the - * string can be shared between several ropes, e.g. for indexing - * purposes. - */ - pub struct Leaf { - byte_offset: uint, - byte_len: uint, - char_len: uint, - content: @~str, - } - - /** - * A node obtained from the concatenation of two other nodes - * - * # Fields - * - * * left - The node containing the beginning of the text. - * * right - The node containing the end of the text. - * * char_len - The number of chars contained in all leaves of this node. - * * byte_len - The number of bytes in the subrope. - * - * Used to pre-allocate the correct amount of storage for - * serialization. - * - * * height - Height of the subrope. - * - * Used for rebalancing and to allocate stacks for traversals. - */ - pub struct Concat { - //FIXME (#2744): Perhaps a `vec` instead of `left`/`right` - left: @Node, - right: @Node, - char_len: uint, - byte_len: uint, - height: uint, - } - - pub enum Node { - /// A leaf consisting in a `str` - Leaf(Leaf), - /// The concatenation of two ropes - Concat(Concat), - } - - /** - * The maximal number of chars that _should_ be permitted in a single node - * - * This is not a strict value - */ - pub static HINT_MAX_LEAF_CHAR_LEN: uint = 256u; - - /** - * The maximal height that _should_ be permitted in a tree. - * - * This is not a strict value - */ - pub static HINT_MAX_NODE_HEIGHT: uint = 16u; - - /** - * Adopt a string as a node. - * - * If the string is longer than `max_leaf_char_len`, it is - * logically split between as many leaves as necessary. Regardless, - * the string itself is not copied. - * - * Performance note: The complexity of this function is linear in - * the length of `str`. - */ - pub fn of_str(str: @~str) -> @Node { - return of_substr(str, 0u, str.len()); - } - - /** - * Adopt a slice of a string as a node. - * - * If the slice is longer than `max_leaf_char_len`, it is logically split - * between as many leaves as necessary. Regardless, the string itself - * is not copied - * - * # Arguments - * - * * byte_start - The byte offset where the slice of `str` starts. - * * byte_len - The number of bytes from `str` to use. - * - * # Safety note - * - * Behavior is undefined if `byte_start` or `byte_len` do not represent - * valid positions in `str` - */ - pub fn of_substr(str: @~str, byte_start: uint, byte_len: uint) -> @Node { - return of_substr_unsafer(str, byte_start, byte_len, - str.slice(byte_start, byte_start + byte_len).char_len()); - } - - /** - * Adopt a slice of a string as a node. - * - * If the slice is longer than `max_leaf_char_len`, it is logically split - * between as many leaves as necessary. Regardless, the string itself - * is not copied - * - * # Arguments - * - * * byte_start - The byte offset where the slice of `str` starts. - * * byte_len - The number of bytes from `str` to use. - * * char_len - The number of chars in `str` in the interval - * [byte_start, byte_start+byte_len) - * - * # Safety notes - * - * * Behavior is undefined if `byte_start` or `byte_len` do not represent - * valid positions in `str` - * * Behavior is undefined if `char_len` does not accurately represent the - * number of chars between byte_start and byte_start+byte_len - */ - pub fn of_substr_unsafer(str: @~str, byte_start: uint, byte_len: uint, - char_len: uint) -> @Node { - assert!((byte_start + byte_len <= str.len())); - let candidate = @Leaf(Leaf { - byte_offset: byte_start, - byte_len: byte_len, - char_len: char_len, - content: str, - }); - if char_len <= HINT_MAX_LEAF_CHAR_LEN { - return candidate; - } else { - //Firstly, split `str` in slices of HINT_MAX_LEAF_CHAR_LEN - let mut leaves = uint::div_ceil(char_len, HINT_MAX_LEAF_CHAR_LEN); - //Number of leaves - let mut nodes = vec::from_elem(leaves, candidate); - - let mut i = 0u; - let mut offset = byte_start; - let first_leaf_char_len = - if char_len%HINT_MAX_LEAF_CHAR_LEN == 0u { - HINT_MAX_LEAF_CHAR_LEN - } else { - char_len%HINT_MAX_LEAF_CHAR_LEN - }; - while i < leaves { - let chunk_char_len: uint = - if i == 0u { first_leaf_char_len } - else { HINT_MAX_LEAF_CHAR_LEN }; - let chunk_byte_len = - str.slice_from(offset).slice_chars(0, chunk_char_len).len(); - nodes[i] = @Leaf(Leaf { - byte_offset: offset, - byte_len: chunk_byte_len, - char_len: chunk_char_len, - content: str, - }); - - offset += chunk_byte_len; - i += 1u; - } - - //Then, build a tree from these slices by collapsing them - while leaves > 1u { - i = 0u; - while i < leaves - 1u {//Concat nodes 0 with 1, 2 with 3 etc. - nodes[i/2u] = concat2(nodes[i], nodes[i + 1u]); - i += 2u; - } - if i == leaves - 1u { - //And don't forget the last node if it is in even position - nodes[i/2u] = nodes[i]; - } - leaves = uint::div_ceil(leaves, 2u); - } - return nodes[0u]; - } - } - - pub fn byte_len(node: @Node) -> uint { - //FIXME (#2744): Could we do this without the pattern-matching? - match (*node) { - Leaf(y) => y.byte_len, - Concat(ref y) => y.byte_len - } - } - - pub fn char_len(node: @Node) -> uint { - match (*node) { - Leaf(y) => y.char_len, - Concat(ref y) => y.char_len - } - } - - /** - * Concatenate a forest of nodes into one tree. - * - * # Arguments - * - * * forest - The forest. This vector is progressively rewritten during - * execution and should be discarded as meaningless afterwards. - */ - pub fn tree_from_forest_destructive(forest: &mut [@Node]) -> @Node { - let mut i; - let mut len = forest.len(); - while len > 1u { - i = 0u; - while i < len - 1u {//Concat nodes 0 with 1, 2 with 3 etc. - let mut left = forest[i]; - let mut right = forest[i+1u]; - let left_len = char_len(left); - let right_len= char_len(right); - let mut left_height= height(left); - let mut right_height=height(right); - if left_len + right_len > HINT_MAX_LEAF_CHAR_LEN { - if left_len <= HINT_MAX_LEAF_CHAR_LEN { - left = flatten(left); - left_height = height(left); - } - if right_len <= HINT_MAX_LEAF_CHAR_LEN { - right = flatten(right); - right_height = height(right); - } - } - if left_height >= HINT_MAX_NODE_HEIGHT { - left = of_substr_unsafer(@serialize_node(left), - 0u,byte_len(left), - left_len); - } - if right_height >= HINT_MAX_NODE_HEIGHT { - right = of_substr_unsafer(@serialize_node(right), - 0u,byte_len(right), - right_len); - } - forest[i/2u] = concat2(left, right); - i += 2u; - } - if i == len - 1u { - //And don't forget the last node if it is in even position - forest[i/2u] = forest[i]; - } - len = uint::div_ceil(len, 2u); - } - return forest[0]; - } - - pub fn serialize_node(node: @Node) -> ~str { - unsafe { - let mut buf = vec::from_elem(byte_len(node), 0); - let mut offset = 0u;//Current position in the buffer - let mut it = leaf_iterator::start(node); - loop { - match leaf_iterator::next(&mut it) { - None => break, - Some(x) => { - //FIXME (#2744): Replace with memcpy or something similar - let local_buf: ~[u8] = cast::transmute(copy *x.content); - let mut i = x.byte_offset; - while i < x.byte_len { - buf[offset] = local_buf[i]; - offset += 1u; - i += 1u; - } - cast::forget(local_buf); - } - } - } - return cast::transmute(buf); - } - } - - /** - * Replace a subtree by a single leaf with the same contents. - * - * * Performance note - * - * This function executes in linear time. - */ - pub fn flatten(node: @Node) -> @Node { - match (*node) { - Leaf(_) => node, - Concat(ref x) => { - @Leaf(Leaf { - byte_offset: 0u, - byte_len: x.byte_len, - char_len: x.char_len, - content: @serialize_node(node), - }) - } - } - } - - /** - * Balance a node. - * - * # Algorithm - * - * * if the node height is smaller than `HINT_MAX_NODE_HEIGHT`, do nothing - * * otherwise, gather all leaves as a forest, rebuild a balanced node, - * concatenating small leaves along the way - * - * # Return value - * - * * `None` if no transformation happened - * * `Some(x)` otherwise, in which case `x` has the same contents - * as `node` bot lower height and/or fragmentation. - */ - pub fn bal(node: @Node) -> Option<@Node> { - if height(node) < HINT_MAX_NODE_HEIGHT { return None; } - //1. Gather all leaves as a forest - let mut forest = ~[]; - let mut it = leaf_iterator::start(node); - loop { - match leaf_iterator::next(&mut it) { - None => break, - Some(x) => forest.push(@Leaf(x)) - } - } - //2. Rebuild tree from forest - let root = @*tree_from_forest_destructive(forest); - return Some(root); - - } - - /** - * Compute the subnode of a node. - * - * # Arguments - * - * * node - A node - * * byte_offset - A byte offset in `node` - * * byte_len - The number of bytes to return - * - * # Performance notes - * - * * this function performs no copying; - * * this function executes in a time proportional to the height of `node` - * - * # Safety notes - * - * This function fails if `byte_offset` or `byte_len` do not represent - * valid positions in `node`. - */ - pub fn sub_bytes(node: @Node, byte_offset: uint, - byte_len: uint) -> @Node { - let mut node = node; - let mut byte_offset = byte_offset; - loop { - if byte_offset == 0u && byte_len == node::byte_len(node) { - return node; - } - match (*node) { - node::Leaf(x) => { - let char_len = - x.content.slice(byte_offset, byte_offset + byte_len).char_len(); - return @Leaf(Leaf { - byte_offset: byte_offset, - byte_len: byte_len, - char_len: char_len, - content: x.content, - }); - } - node::Concat(ref x) => { - let left_len: uint = node::byte_len(x.left); - if byte_offset <= left_len { - if byte_offset + byte_len <= left_len { - //Case 1: Everything fits in x.left, tail-call - node = x.left; - } else { - //Case 2: A (non-empty, possibly full) suffix - //of x.left and a (non-empty, possibly full) prefix - //of x.right - let left_result = - sub_bytes(x.left, byte_offset, left_len); - let right_result = - sub_bytes(x.right, 0u, left_len - byte_offset); - return concat2(left_result, right_result); - } - } else { - //Case 3: Everything fits in x.right - byte_offset -= left_len; - node = x.right; - } - } - } - }; - } - - /** - * Compute the subnode of a node. - * - * # Arguments - * - * * node - A node - * * char_offset - A char offset in `node` - * * char_len - The number of chars to return - * - * # Performance notes - * - * * this function performs no copying; - * * this function executes in a time proportional to the height of `node` - * - * # Safety notes - * - * This function fails if `char_offset` or `char_len` do not represent - * valid positions in `node`. - */ - pub fn sub_chars(node: @Node, char_offset: uint, - char_len: uint) -> @Node { - let mut node = node; - let mut char_offset = char_offset; - loop { - match (*node) { - node::Leaf(x) => { - if char_offset == 0u && char_len == x.char_len { - return node; - } - let byte_offset = - x.content.slice_chars(0, char_offset).len(); - let byte_len = - x.content.slice_from(byte_offset).slice_chars(0, char_len).len(); - return @Leaf(Leaf { - byte_offset: byte_offset, - byte_len: byte_len, - char_len: char_len, - content: x.content, - }); - } - node::Concat(ref x) => { - if char_offset == 0u && char_len == x.char_len {return node;} - let left_len : uint = node::char_len(x.left); - if char_offset <= left_len { - if char_offset + char_len <= left_len { - //Case 1: Everything fits in x.left, tail call - node = x.left; - } else { - //Case 2: A (non-empty, possibly full) suffix - //of x.left and a (non-empty, possibly full) prefix - //of x.right - let left_result = - sub_chars(x.left, char_offset, left_len); - let right_result = - sub_chars(x.right, 0u, left_len - char_offset); - return concat2(left_result, right_result); - } - } else { - //Case 3: Everything fits in x.right, tail call - node = x.right; - char_offset -= left_len; - } - } - } - }; - } - - pub fn concat2(left: @Node, right: @Node) -> @Node { - @Concat(Concat { - left: left, - right: right, - char_len: char_len(left) + char_len(right), - byte_len: byte_len(left) + byte_len(right), - height: uint::max(height(left), height(right)) + 1u, - }) - } - - pub fn height(node: @Node) -> uint { - match (*node) { - Leaf(_) => 0u, - Concat(ref x) => x.height, - } - } - - pub fn cmp(a: @Node, b: @Node) -> int { - let mut ita = char_iterator::start(a); - let mut itb = char_iterator::start(b); - let mut result = 0; - while result == 0 { - match (char_iterator::next(&mut ita), char_iterator::next(&mut itb)) - { - (None, None) => break, - (Some(chara), Some(charb)) => { - result = chara.cmp(&charb) as int; - } - (Some(_), _) => { - result = 1; - } - (_, Some(_)) => { - result = -1; - } - } - } - return result; - } - - pub fn loop_chars(node: @Node, it: &fn(c: char) -> bool) -> bool { - return loop_leaves(node,|leaf| { - leaf.content.slice(leaf.byte_offset, leaf.byte_len).iter().all(|c| it(c)) - }); - } - - /** - * Loop through a node, leaf by leaf - * - * # Arguments - * - * * rope - A node to traverse. - * * it - A block to execute with each consecutive leaf of the node. - * Return `true` to continue, `false` to stop - * - * # Arguments - * - * `true` If execution proceeded correctly, `false` if it was interrupted, - * that is if `it` returned `false` at any point. - */ - pub fn loop_leaves(node: @Node, it: &fn(Leaf) -> bool) -> bool{ - let mut current = node; - loop { - match (*current) { - Leaf(x) => return it(x), - Concat(ref x) => if loop_leaves(x.left, |l| it(l)) { //non tail call - current = x.right; //tail call - } else { - return false; - } - } - }; - } - - /** - * # Arguments - * - * * pos - A position in the rope - * - * # Return value - * - * The character at position `pos` - * - * # Safety notes - * - * The function will fail if `pos` is not a valid position in the rope. - * - * Performance note: This function executes in a time - * proportional to the height of the rope + the (bounded) - * length of the largest leaf. - */ - pub fn char_at(mut node: @Node, mut pos: uint) -> char { - loop { - match *node { - Leaf(x) => return x.content.char_at(pos), - Concat(Concat {left, right, _}) => { - let left_len = char_len(left); - node = if left_len > pos { left } - else { pos -= left_len; right }; - } - } - }; - } - - pub mod leaf_iterator { - - use rope::node::{Concat, Leaf, Node, height}; - - use std::vec; - - pub struct T { - stack: ~[@Node], - stackpos: int, - } - - pub fn empty() -> T { - let stack : ~[@Node] = ~[]; - T { stack: stack, stackpos: -1 } - } - - pub fn start(node: @Node) -> T { - let stack = vec::from_elem(height(node)+1u, node); - T { - stack: stack, - stackpos: 0, - } - } - - pub fn next(it: &mut T) -> Option { - if it.stackpos < 0 { return None; } - loop { - let current = it.stack[it.stackpos]; - it.stackpos -= 1; - match (*current) { - Concat(ref x) => { - it.stackpos += 1; - it.stack[it.stackpos] = x.right; - it.stackpos += 1; - it.stack[it.stackpos] = x.left; - } - Leaf(x) => return Some(x) - } - }; - } - } - - pub mod char_iterator { - - use rope::node::{Leaf, Node}; - use rope::node::leaf_iterator; - - pub struct T { - leaf_iterator: leaf_iterator::T, - leaf: Option, - leaf_byte_pos: uint, - } - - pub fn start(node: @Node) -> T { - T { - leaf_iterator: leaf_iterator::start(node), - leaf: None, - leaf_byte_pos: 0u, - } - } - - pub fn empty() -> T { - T { - leaf_iterator: leaf_iterator::empty(), - leaf: None, - leaf_byte_pos: 0u, - } - } - - pub fn next(it: &mut T) -> Option { - loop { - match get_current_or_next_leaf(it) { - None => return None, - Some(_) => { - let next_char = get_next_char_in_leaf(it); - match next_char { - None => loop, - Some(_) => return next_char - } - } - } - }; - } - - pub fn get_current_or_next_leaf(it: &mut T) -> Option { - match it.leaf { - Some(_) => return it.leaf, - None => { - let next = leaf_iterator::next(&mut it.leaf_iterator); - match next { - None => return None, - Some(_) => { - it.leaf = next; - it.leaf_byte_pos = 0u; - return next; - } - } - } - } - } - - pub fn get_next_char_in_leaf(it: &mut T) -> Option { - match copy it.leaf { - None => return None, - Some(aleaf) => { - if it.leaf_byte_pos >= aleaf.byte_len { - //We are actually past the end of the leaf - it.leaf = None; - return None - } else { - let range = - aleaf.content.char_range_at((*it).leaf_byte_pos + aleaf.byte_offset); - let ch = range.ch; - let next = range.next; - (*it).leaf_byte_pos = next - aleaf.byte_offset; - return Some(ch) - } - } - } - } - } -} - -#[cfg(test)] -mod tests { - - use rope::*; - - use std::uint; - use std::vec; - - //Utility function, used for sanity check - fn rope_to_string(r: Rope) -> ~str { - match (r) { - node::Empty => return ~"", - node::Content(x) => { - let mut str = ~""; - fn aux(str: &mut ~str, node: @node::Node) { - match (*node) { - node::Leaf(x) => { - str.push_str(x.content.slice(x.byte_offset, x.byte_offset + x.byte_len)); - } - node::Concat(ref x) => { - aux(str, x.left); - aux(str, x.right); - } - } - } - aux(&mut str, x); - return str - } - } - } - - - #[test] - fn trivial() { - assert_eq!(char_len(empty()), 0u); - assert_eq!(byte_len(empty()), 0u); - } - - #[test] - fn of_string1() { - let sample = @~"0123456789ABCDE"; - let r = of_str(sample); - - assert_eq!(char_len(r), sample.char_len()); - assert!(rope_to_string(r) == *sample); - } - - #[test] - fn of_string2() { - let buf = @ mut ~"1234567890"; - let mut i = 0; - while i < 10 { - let a = copy *buf; - let b = copy *buf; - *buf = a + b; - i+=1; - } - let sample = @copy *buf; - let r = of_str(sample); - assert_eq!(char_len(r), sample.char_len()); - assert!(rope_to_string(r) == *sample); - - let mut string_iter = 0u; - let string_len = sample.len(); - let mut rope_iter = iterator::char::start(r); - let mut equal = true; - while equal { - match (node::char_iterator::next(&mut rope_iter)) { - None => { - if string_iter < string_len { - equal = false; - } break; } - Some(c) => { - let range = sample.char_range_at(string_iter); - string_iter = range.next; - if range.ch != c { equal = false; break; } - } - } - } - - assert!(equal); - } - - #[test] - fn iter1() { - let buf = @ mut ~"1234567890"; - let mut i = 0; - while i < 10 { - let a = copy *buf; - let b = copy *buf; - *buf = a + b; - i+=1; - } - let sample = @copy *buf; - let r = of_str(sample); - - let mut len = 0u; - let mut it = iterator::char::start(r); - loop { - match (node::char_iterator::next(&mut it)) { - None => break, - Some(_) => len += 1u - } - } - - assert_eq!(len, sample.char_len()); - } - - #[test] - fn bal1() { - let init = @~"1234567890"; - let buf = @mut copy *init; - let mut i = 0; - while i < 8 { - let a = copy *buf; - let b = copy *buf; - *buf = a + b; - i+=1; - } - let sample = @copy *buf; - let r1 = of_str(sample); - let mut r2 = of_str(init); - i = 0; - while i < 8 { r2 = append_rope(r2, r2); i+= 1;} - - - assert!(eq(r1, r2)); - let r3 = bal(r2); - assert_eq!(char_len(r1), char_len(r3)); - - assert!(eq(r1, r3)); - } - - #[test] - #[ignore] - fn char_at1() { - //Generate a large rope - let mut r = of_str(@~"123456789"); - for uint::range(0u, 10u) |_i| { - r = append_rope(r, r); - } - - //Copy it in the slowest possible way - let mut r2 = empty(); - for uint::range(0u, char_len(r)) |i| { - r2 = append_char(r2, char_at(r, i)); - } - assert!(eq(r, r2)); - - let mut r3 = empty(); - for uint::range(0u, char_len(r)) |i| { - r3 = prepend_char(r3, char_at(r, char_len(r) - i - 1u)); - } - assert!(eq(r, r3)); - - //Additional sanity checks - let balr = bal(r); - let bal2 = bal(r2); - let bal3 = bal(r3); - assert!(eq(r, balr)); - assert!(eq(r, bal2)); - assert!(eq(r, bal3)); - assert!(eq(r2, r3)); - assert!(eq(bal2, bal3)); - } - - #[test] - fn concat1() { - //Generate a reasonable rope - let chunk = of_str(@~"123456789"); - let mut r = empty(); - for uint::range(0u, 10u) |_i| { - r = append_rope(r, chunk); - } - - //Same rope, obtained with rope::concat - let r2 = concat(vec::from_elem(10u, chunk)); - - assert!(eq(r, r2)); - } -} diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 564c58f7097e..748d5f05aae0 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -13,8 +13,7 @@ * * Strings are a packed UTF-8 representation of text, stored as null * terminated buffers of u8 bytes. Strings should be indexed in bytes, - * for efficiency, but UTF-8 unsafe operations should be avoided. For - * some heavy-duty uses, try extra::rope. + * for efficiency, but UTF-8 unsafe operations should be avoided. */ use at_vec; From e6f9b08610050f8e98903829056cf6ff83e95ef3 Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Wed, 3 Jul 2013 11:30:12 -0700 Subject: [PATCH 72/93] Implement size_hint() on all remaining Iterators Add size_hint() to the Iterators in libextra and the Iterator in libsyntax. Skip deque for the moment, as it's being worked on elsewhere. --- src/libextra/priority_queue.rs | 3 +++ src/libextra/treemap.rs | 11 +++++++++-- src/libsyntax/opt_vec.rs | 8 ++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/libextra/priority_queue.rs b/src/libextra/priority_queue.rs index 3d1ca4a9818b..1f7ba9f65303 100644 --- a/src/libextra/priority_queue.rs +++ b/src/libextra/priority_queue.rs @@ -186,6 +186,9 @@ pub struct PriorityQueueIterator <'self, T> { impl<'self, T> Iterator<&'self T> for PriorityQueueIterator<'self, T> { #[inline] fn next(&mut self) -> Option<(&'self T)> { self.iter.next() } + + #[inline] + fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } } #[cfg(test)] diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index 5e898f8e59d9..b7df27c0e497 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -196,14 +196,15 @@ impl TreeMap { /// Get a lazy iterator over the key-value pairs in the map. /// Requires that it be frozen (immutable). pub fn iter<'a>(&'a self) -> TreeMapIterator<'a, K, V> { - TreeMapIterator{stack: ~[], node: &self.root} + TreeMapIterator{stack: ~[], node: &self.root, remaining: self.length} } } /// Lazy forward iterator over a map pub struct TreeMapIterator<'self, K, V> { priv stack: ~[&'self ~TreeNode], - priv node: &'self Option<~TreeNode> + priv node: &'self Option<~TreeNode>, + priv remaining: uint } impl<'self, K, V> Iterator<(&'self K, &'self V)> for TreeMapIterator<'self, K, V> { @@ -220,12 +221,18 @@ impl<'self, K, V> Iterator<(&'self K, &'self V)> for TreeMapIterator<'self, K, V None => { let res = self.stack.pop(); self.node = &res.right; + self.remaining -= 1; return Some((&res.key, &res.value)); } } } None } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + (self.remaining, Some(self.remaining)) + } } impl<'self, T> Iterator<&'self T> for TreeSetIterator<'self, T> { diff --git a/src/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs index bf8c5ae462bf..8e2da3d6eb1a 100644 --- a/src/libsyntax/opt_vec.rs +++ b/src/libsyntax/opt_vec.rs @@ -146,4 +146,12 @@ impl<'self, T> Iterator<&'self T> for OptVecIterator<'self, T> { None => None } } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + match self.iter { + Some(ref x) => x.size_hint(), + None => (0, Some(0)) + } + } } From a69eb952336bb3d483dd046373daa8e3948390a7 Mon Sep 17 00:00:00 2001 From: James Miller Date: Fri, 5 Jul 2013 20:28:53 +1200 Subject: [PATCH 73/93] Stop allocating view_items with @ --- src/librustc/front/config.rs | 15 +++++++-------- src/librustc/front/std_inject.rs | 4 ++-- src/librustc/front/test.rs | 7 +++---- src/librustc/metadata/creader.rs | 2 +- src/librustc/middle/resolve.rs | 4 ++-- src/libsyntax/ast.rs | 6 +++--- src/libsyntax/ext/build.rs | 22 +++++++++++----------- src/libsyntax/fold.rs | 13 ++++++------- src/libsyntax/parse/parser.rs | 14 +++++++------- src/libsyntax/print/pprust.rs | 8 ++++---- src/libsyntax/visit.rs | 12 ++++++------ 11 files changed, 52 insertions(+), 55 deletions(-) diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs index 7d478afee41a..12c7a0843ce4 100644 --- a/src/librustc/front/config.rs +++ b/src/librustc/front/config.rs @@ -12,7 +12,7 @@ use std::option; use syntax::{ast, fold, attr}; -type in_cfg_pred = @fn(attrs: ~[ast::attribute]) -> bool; +type in_cfg_pred = @fn(attrs: &[ast::attribute]) -> bool; struct Context { in_cfg: in_cfg_pred @@ -50,8 +50,7 @@ fn filter_item(cx: @Context, item: @ast::item) -> if item_in_cfg(cx, item) { option::Some(item) } else { option::None } } -fn filter_view_item(cx: @Context, view_item: @ast::view_item - )-> Option<@ast::view_item> { +fn filter_view_item<'r>(cx: @Context, view_item: &'r ast::view_item)-> Option<&'r ast::view_item> { if view_item_in_cfg(cx, view_item) { option::Some(view_item) } else { @@ -64,7 +63,7 @@ fn fold_mod(cx: @Context, m: &ast::_mod, fld: @fold::ast_fold) -> ast::_mod { filter_item(cx, *a).chain(|x| fld.fold_item(x)) }.collect(); let filtered_view_items = do m.view_items.iter().filter_map |a| { - filter_view_item(cx, *a).map(|x| fld.fold_view_item(*x)) + filter_view_item(cx, a).map(|&x| fld.fold_view_item(x)) }.collect(); ast::_mod { view_items: filtered_view_items, @@ -86,7 +85,7 @@ fn fold_foreign_mod( ) -> ast::foreign_mod { let filtered_items = nm.items.iter().filter_map(|a| filter_foreign_item(cx, *a)).collect(); let filtered_view_items = do nm.view_items.iter().filter_map |a| { - filter_view_item(cx, *a).map(|x| fld.fold_view_item(*x)) + filter_view_item(cx, a).map(|&x| fld.fold_view_item(x)) }.collect(); ast::foreign_mod { sort: nm.sort, @@ -141,7 +140,7 @@ fn fold_block( filter_stmt(cx, *a).chain(|stmt| fld.fold_stmt(stmt)) }.collect(); let filtered_view_items = do b.view_items.iter().filter_map |a| { - filter_view_item(cx, *a).map(|x| fld.fold_view_item(*x)) + filter_view_item(cx, a).map(|&x| fld.fold_view_item(x)) }.collect(); ast::blk_ { view_items: filtered_view_items, @@ -160,8 +159,8 @@ fn foreign_item_in_cfg(cx: @Context, item: @ast::foreign_item) -> bool { return (cx.in_cfg)(/*bad*/copy item.attrs); } -fn view_item_in_cfg(cx: @Context, item: @ast::view_item) -> bool { - return (cx.in_cfg)(/*bad*/copy item.attrs); +fn view_item_in_cfg(cx: @Context, item: &ast::view_item) -> bool { + return (cx.in_cfg)(item.attrs); } fn method_in_cfg(cx: @Context, meth: @ast::method) -> bool { diff --git a/src/librustc/front/std_inject.rs b/src/librustc/front/std_inject.rs index 735fe54f3480..16a5c00b132d 100644 --- a/src/librustc/front/std_inject.rs +++ b/src/librustc/front/std_inject.rs @@ -41,7 +41,7 @@ fn inject_libstd_ref(sess: Session, crate: &ast::crate) -> @ast::crate { let precursor = @fold::AstFoldFns { fold_crate: |crate, span, fld| { let n1 = sess.next_node_id(); - let vi1 = @ast::view_item { + let vi1 = ast::view_item { node: ast::view_item_extern_mod( sess.ident_of("std"), ~[], n1), attrs: ~[ @@ -87,7 +87,7 @@ fn inject_libstd_ref(sess: Session, crate: &ast::crate) -> @ast::crate { }; let vp = @spanned(ast::view_path_glob(prelude_path, n2)); - let vi2 = @ast::view_item { node: ast::view_item_use(~[vp]), + let vi2 = ast::view_item { node: ast::view_item_use(~[vp]), attrs: ~[], vis: ast::private, span: dummy_sp() }; diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs index bbac4a2907c0..ea48d194993e 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -272,7 +272,7 @@ mod __test { */ -fn mk_std(cx: &TestCtxt) -> @ast::view_item { +fn mk_std(cx: &TestCtxt) -> ast::view_item { let vers = ast::lit_str(@"0.7"); let vers = nospan(vers); let mi = ast::meta_name_value(@"vers", vers); @@ -287,13 +287,12 @@ fn mk_std(cx: &TestCtxt) -> @ast::view_item { ast::view_item_extern_mod(id_std, ~[@mi], cx.sess.next_node_id()) }; - let vi = ast::view_item { + ast::view_item { node: vi, attrs: ~[], vis: ast::public, span: dummy_sp() - }; - return @vi; + } } fn mk_test_module(cx: &TestCtxt) -> @ast::item { diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 2a712b075647..8c62f4dbbe35 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -136,7 +136,7 @@ fn visit_crate(e: &Env, c: &ast::crate) { } } -fn visit_view_item(e: @mut Env, i: @ast::view_item) { +fn visit_view_item(e: @mut Env, i: &ast::view_item) { match i.node { ast::view_item_extern_mod(ident, ref meta_items, id) => { debug!("resolving extern mod stmt. ident: %?, meta: %?", diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index dc55dcad99d1..fb9159d26bfc 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -1432,7 +1432,7 @@ impl Resolver { /// Constructs the reduced graph for one 'view item'. View items consist /// of imports and use directives. pub fn build_reduced_graph_for_view_item(@mut self, - view_item: @view_item, + view_item: &view_item, (parent, _): (ReducedGraphParent, vt)) { @@ -5295,7 +5295,7 @@ impl Resolver { visit_crate(self.crate, ((), vt)); } - pub fn check_for_item_unused_imports(&mut self, vi: @view_item) { + pub fn check_for_item_unused_imports(&mut self, vi: &view_item) { // Ignore public import statements because there's no way to be sure // whether they're used or not. Also ignore imports with a dummy span // because this means that they were generated in some fashion by the diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 2603cbb2dd7c..ffbd61b15edd 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -219,7 +219,7 @@ pub type blk = spanned; #[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct blk_ { - view_items: ~[@view_item], + view_items: ~[view_item], stmts: ~[@stmt], expr: Option<@expr>, id: node_id, @@ -827,7 +827,7 @@ pub struct method { #[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct _mod { - view_items: ~[@view_item], + view_items: ~[view_item], items: ~[@item], } @@ -839,7 +839,7 @@ pub enum foreign_mod_sort { named, anonymous } pub struct foreign_mod { sort: foreign_mod_sort, abis: AbiSet, - view_items: ~[@view_item], + view_items: ~[view_item], items: ~[@foreign_item], } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 2c1b4cfc5915..e2b8ff3c0302 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -80,7 +80,7 @@ pub trait AstBuilder { fn blk(&self, span: span, stmts: ~[@ast::stmt], expr: Option<@ast::expr>) -> ast::blk; fn blk_expr(&self, expr: @ast::expr) -> ast::blk; fn blk_all(&self, span: span, - view_items: ~[@ast::view_item], + view_items: ~[ast::view_item], stmts: ~[@ast::stmt], expr: Option<@ast::expr>) -> ast::blk; @@ -202,7 +202,7 @@ pub trait AstBuilder { fn item_mod(&self, span: span, name: ident, attrs: ~[ast::attribute], - vi: ~[@ast::view_item], items: ~[@ast::item]) -> @ast::item; + vi: ~[ast::view_item], items: ~[@ast::item]) -> @ast::item; fn item_ty_poly(&self, span: span, @@ -218,11 +218,11 @@ pub trait AstBuilder { fn meta_name_value(&self, sp: span, name: @str, value: ast::lit_) -> @ast::meta_item; fn view_use(&self, sp: span, - vis: ast::visibility, vp: ~[@ast::view_path]) -> @ast::view_item; + vis: ast::visibility, vp: ~[@ast::view_path]) -> ast::view_item; fn view_use_list(&self, sp: span, vis: ast::visibility, - path: ~[ast::ident], imports: &[ast::ident]) -> @ast::view_item; + path: ~[ast::ident], imports: &[ast::ident]) -> ast::view_item; fn view_use_glob(&self, sp: span, - vis: ast::visibility, path: ~[ast::ident]) -> @ast::view_item; + vis: ast::visibility, path: ~[ast::ident]) -> ast::view_item; } impl AstBuilder for @ExtCtxt { @@ -400,7 +400,7 @@ impl AstBuilder for @ExtCtxt { } fn blk_all(&self, span: span, - view_items: ~[@ast::view_item], + view_items: ~[ast::view_item], stmts: ~[@ast::stmt], expr: Option<@ast::expr>) -> ast::blk { respan(span, @@ -762,7 +762,7 @@ impl AstBuilder for @ExtCtxt { fn item_mod(&self, span: span, name: ident, attrs: ~[ast::attribute], - vi: ~[@ast::view_item], + vi: ~[ast::view_item], items: ~[@ast::item]) -> @ast::item { self.item( span, @@ -804,8 +804,8 @@ impl AstBuilder for @ExtCtxt { } fn view_use(&self, sp: span, - vis: ast::visibility, vp: ~[@ast::view_path]) -> @ast::view_item { - @ast::view_item { + vis: ast::visibility, vp: ~[@ast::view_path]) -> ast::view_item { + ast::view_item { node: ast::view_item_use(vp), attrs: ~[], vis: vis, @@ -814,7 +814,7 @@ impl AstBuilder for @ExtCtxt { } fn view_use_list(&self, sp: span, vis: ast::visibility, - path: ~[ast::ident], imports: &[ast::ident]) -> @ast::view_item { + path: ~[ast::ident], imports: &[ast::ident]) -> ast::view_item { let imports = do imports.map |id| { respan(sp, ast::path_list_ident_ { name: *id, id: self.next_id() }) }; @@ -827,7 +827,7 @@ impl AstBuilder for @ExtCtxt { } fn view_use_glob(&self, sp: span, - vis: ast::visibility, path: ~[ast::ident]) -> @ast::view_item { + vis: ast::visibility, path: ~[ast::ident]) -> ast::view_item { self.view_use(sp, vis, ~[@respan(sp, ast::view_path_glob(self.path(sp, path), self.next_id()))]) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 96d7685353b2..b4d64ba3e2dc 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -16,7 +16,7 @@ use opt_vec::OptVec; pub trait ast_fold { fn fold_crate(@self, &crate) -> crate; - fn fold_view_item(@self, @view_item) -> @view_item; + fn fold_view_item(@self, &view_item) -> view_item; fn fold_foreign_item(@self, @foreign_item) -> @foreign_item; fn fold_item(@self, @item) -> Option<@item>; fn fold_struct_field(@self, @struct_field) -> @struct_field; @@ -372,7 +372,7 @@ fn noop_fold_method(m: @method, fld: @ast_fold) -> @method { pub fn noop_fold_block(b: &blk_, fld: @ast_fold) -> blk_ { - let view_items = b.view_items.map(|x| fld.fold_view_item(*x)); + let view_items = b.view_items.map(|x| fld.fold_view_item(x)); let mut stmts = ~[]; for b.stmts.iter().advance |stmt| { match fld.fold_stmt(*stmt) { @@ -697,7 +697,7 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ { // ...nor do modules pub fn noop_fold_mod(m: &_mod, fld: @ast_fold) -> _mod { ast::_mod { - view_items: m.view_items.iter().transform(|x| fld.fold_view_item(*x)).collect(), + view_items: m.view_items.iter().transform(|x| fld.fold_view_item(x)).collect(), items: m.items.iter().filter_map(|x| fld.fold_item(*x)).collect(), } } @@ -706,7 +706,7 @@ fn noop_fold_foreign_mod(nm: &foreign_mod, fld: @ast_fold) -> foreign_mod { ast::foreign_mod { sort: nm.sort, abis: nm.abis, - view_items: nm.view_items.iter().transform(|x| fld.fold_view_item(*x)).collect(), + view_items: nm.view_items.iter().transform(|x| fld.fold_view_item(x)).collect(), items: nm.items.iter().transform(|x| fld.fold_foreign_item(*x)).collect(), } } @@ -818,9 +818,8 @@ impl ast_fold for AstFoldFns { let (n, s) = (self.fold_crate)(&c.node, c.span, self as @ast_fold); spanned { node: n, span: (self.new_span)(s) } } - fn fold_view_item(@self, x: @view_item) -> - @view_item { - @ast::view_item { + fn fold_view_item(@self, x: &view_item) -> view_item { + ast::view_item { node: (self.fold_view_item)(&x.node, self as @ast_fold), attrs: x.attrs.iter().transform(|a| fold_attribute_(*a, self as @ast_fold)).collect(), vis: x.vis, diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ae87fd8774a9..35c558c52962 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -115,7 +115,7 @@ pub enum item_or_view_item { iovi_none, iovi_item(@item), iovi_foreign_item(@foreign_item), - iovi_view_item(@view_item) + iovi_view_item(view_item) } #[deriving(Eq)] @@ -208,7 +208,7 @@ fn maybe_append(lhs: ~[attribute], rhs: Option<~[attribute]>) struct ParsedItemsAndViewItems { attrs_remaining: ~[attribute], - view_items: ~[@view_item], + view_items: ~[view_item], items: ~[@item], foreign_items: ~[@foreign_item] } @@ -4074,7 +4074,7 @@ impl Parser { // extern mod foo; let metadata = self.parse_optional_meta(); self.expect(&token::SEMI); - iovi_view_item(@ast::view_item { + iovi_view_item(ast::view_item { node: view_item_extern_mod(ident, metadata, self.get_id()), attrs: copy attrs, vis: visibility, @@ -4308,7 +4308,7 @@ impl Parser { // USE ITEM (iovi_view_item) let view_item = self.parse_use(); self.expect(&token::SEMI); - return iovi_view_item(@ast::view_item { + return iovi_view_item(ast::view_item { node: view_item, attrs: attrs, vis: visibility, @@ -4656,7 +4656,7 @@ impl Parser { &self, attrs: ~[attribute], vis: visibility - ) -> @view_item { + ) -> view_item { let lo = self.span.lo; let node = if self.eat_keyword(keywords::Use) { self.parse_use() @@ -4669,7 +4669,7 @@ impl Parser { self.bug("expected view item"); }; self.expect(&token::SEMI); - @ast::view_item { node: node, + ast::view_item { node: node, attrs: attrs, vis: vis, span: mk_sp(lo, self.last_span.hi) } @@ -4687,7 +4687,7 @@ impl Parser { let mut attrs = vec::append(first_item_attrs, self.parse_outer_attributes()); // First, parse view items. - let mut view_items = ~[]; + let mut view_items : ~[ast::view_item] = ~[]; let mut items = ~[]; let mut done = false; // I think this code would probably read better as a single diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 5e685d85f95d..f6d62e476108 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -352,7 +352,7 @@ pub fn commasep_exprs(s: @ps, b: breaks, exprs: &[@ast::expr]) { pub fn print_mod(s: @ps, _mod: &ast::_mod, attrs: &[ast::attribute]) { print_inner_attributes(s, attrs); for _mod.view_items.iter().advance |vitem| { - print_view_item(s, *vitem); + print_view_item(s, vitem); } for _mod.items.iter().advance |item| { print_item(s, *item); } } @@ -361,7 +361,7 @@ pub fn print_foreign_mod(s: @ps, nmod: &ast::foreign_mod, attrs: &[ast::attribute]) { print_inner_attributes(s, attrs); for nmod.view_items.iter().advance |vitem| { - print_view_item(s, *vitem); + print_view_item(s, vitem); } for nmod.items.iter().advance |item| { print_foreign_item(s, *item); } } @@ -947,7 +947,7 @@ pub fn print_possibly_embedded_block_(s: @ps, print_inner_attributes(s, attrs); - for blk.node.view_items.iter().advance |vi| { print_view_item(s, *vi); } + for blk.node.view_items.iter().advance |vi| { print_view_item(s, vi); } for blk.node.stmts.iter().advance |st| { print_stmt(s, *st); } @@ -1844,7 +1844,7 @@ pub fn print_view_paths(s: @ps, vps: &[@ast::view_path]) { commasep(s, inconsistent, vps, print_view_path); } -pub fn print_view_item(s: @ps, item: @ast::view_item) { +pub fn print_view_item(s: @ps, item: &ast::view_item) { hardbreak_if_not_bol(s); maybe_print_comment(s, item.span.lo); print_outer_attributes(s, item.attrs); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 5bde51ad70fa..944e94ddc0a5 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -72,7 +72,7 @@ pub fn generics_of_fn(fk: &fn_kind) -> Generics { pub struct Visitor { visit_mod: @fn(&_mod, span, node_id, (E, vt)), - visit_view_item: @fn(@view_item, (E, vt)), + visit_view_item: @fn(&view_item, (E, vt)), visit_foreign_item: @fn(@foreign_item, (E, vt)), visit_item: @fn(@item, (E, vt)), visit_local: @fn(@local, (E, vt)), @@ -123,7 +123,7 @@ pub fn visit_crate(c: &crate, (e, v): (E, vt)) { } pub fn visit_mod(m: &_mod, _sp: span, _id: node_id, (e, v): (E, vt)) { - for m.view_items.iter().advance |vi| { (v.visit_view_item)(*vi, (copy e, v)); } + for m.view_items.iter().advance |vi| { (v.visit_view_item)(vi, (copy e, v)); } for m.items.iter().advance |i| { (v.visit_item)(*i, (copy e, v)); } } @@ -166,7 +166,7 @@ pub fn visit_item(i: &item, (e, v): (E, vt)) { } item_mod(ref m) => (v.visit_mod)(m, i.span, i.id, (e, v)), item_foreign_mod(ref nm) => { - for nm.view_items.iter().advance |vi| { (v.visit_view_item)(*vi, (copy e, v)); } + for nm.view_items.iter().advance |vi| { (v.visit_view_item)(vi, (copy e, v)); } for nm.items.iter().advance |ni| { (v.visit_foreign_item)(*ni, (copy e, v)); } } item_ty(t, ref tps) => { @@ -414,7 +414,7 @@ pub fn visit_struct_field(sf: &struct_field, (e, v): (E, vt)) { pub fn visit_block(b: &blk, (e, v): (E, vt)) { for b.node.view_items.iter().advance |vi| { - (v.visit_view_item)(*vi, (copy e, v)); + (v.visit_view_item)(vi, (copy e, v)); } for b.node.stmts.iter().advance |s| { (v.visit_stmt)(*s, (copy e, v)); @@ -568,7 +568,7 @@ pub fn visit_arm(a: &arm, (e, v): (E, vt)) { pub struct SimpleVisitor { visit_mod: @fn(&_mod, span, node_id), - visit_view_item: @fn(@view_item), + visit_view_item: @fn(&view_item), visit_foreign_item: @fn(@foreign_item), visit_item: @fn(@item), visit_local: @fn(@local), @@ -629,7 +629,7 @@ pub fn mk_simple_visitor(v: simple_visitor) -> vt<()> { f(m, sp, id); visit_mod(m, sp, id, (e, v)); } - fn v_view_item(f: @fn(@view_item), vi: @view_item, (e, v): ((), vt<()>)) { + fn v_view_item(f: @fn(&view_item), vi: &view_item, (e, v): ((), vt<()>)) { f(vi); visit_view_item(vi, (e, v)); } From cd1b6c897911c91167c5a3c5e3c2fa0d9334ad45 Mon Sep 17 00:00:00 2001 From: James Miller Date: Fri, 5 Jul 2013 22:15:21 +1200 Subject: [PATCH 74/93] De-managed ast::Path --- src/librustc/front/std_inject.rs | 2 +- src/librustc/front/test.rs | 8 +-- src/librustc/metadata/encoder.rs | 2 +- src/librustc/middle/check_const.rs | 2 +- src/librustc/middle/pat_util.rs | 4 +- src/librustc/middle/privacy.rs | 4 +- src/librustc/middle/region.rs | 4 +- src/librustc/middle/resolve.rs | 34 ++++++------ src/librustc/middle/trans/_match.rs | 4 +- src/librustc/middle/trans/base.rs | 2 +- src/librustc/middle/trans/consts.rs | 2 +- src/librustc/middle/trans/debuginfo.rs | 4 +- src/librustc/middle/typeck/astconv.rs | 14 ++--- src/librustc/middle/typeck/check/_match.rs | 16 +++--- src/librustc/middle/typeck/check/mod.rs | 8 +-- src/librustc/middle/typeck/collect.rs | 6 +-- src/libsyntax/ast.rs | 22 ++++---- src/libsyntax/ast_map.rs | 2 +- src/libsyntax/ast_util.rs | 6 +-- src/libsyntax/ext/base.rs | 2 +- src/libsyntax/ext/build.rs | 46 ++++++++--------- src/libsyntax/ext/concat_idents.rs | 2 +- src/libsyntax/ext/deriving/generic.rs | 8 +-- src/libsyntax/ext/deriving/ty.rs | 4 +- src/libsyntax/ext/expand.rs | 10 ++-- src/libsyntax/ext/pipes/ast_builder.rs | 26 +++++----- src/libsyntax/fold.rs | 26 +++++----- src/libsyntax/parse/mod.rs | 20 ++++---- src/libsyntax/parse/parser.rs | 60 ++++++++++++---------- src/libsyntax/parse/token.rs | 2 +- src/libsyntax/print/pprust.rs | 36 ++++++------- src/libsyntax/visit.rs | 16 +++--- 32 files changed, 206 insertions(+), 198 deletions(-) diff --git a/src/librustc/front/std_inject.rs b/src/librustc/front/std_inject.rs index 16a5c00b132d..699799929ba0 100644 --- a/src/librustc/front/std_inject.rs +++ b/src/librustc/front/std_inject.rs @@ -75,7 +75,7 @@ fn inject_libstd_ref(sess: Session, crate: &ast::crate) -> @ast::crate { fold_mod: |module, fld| { let n2 = sess.next_node_id(); - let prelude_path = @ast::Path { + let prelude_path = ast::Path { span: dummy_sp(), global: false, idents: ~[ diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs index ea48d194993e..f2670a663ea0 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -342,16 +342,16 @@ fn nospan(t: T) -> codemap::spanned { codemap::spanned { node: t, span: dummy_sp() } } -fn path_node(ids: ~[ast::ident]) -> @ast::Path { - @ast::Path { span: dummy_sp(), +fn path_node(ids: ~[ast::ident]) -> ast::Path { + ast::Path { span: dummy_sp(), global: false, idents: ids, rp: None, types: ~[] } } -fn path_node_global(ids: ~[ast::ident]) -> @ast::Path { - @ast::Path { span: dummy_sp(), +fn path_node_global(ids: ~[ast::ident]) -> ast::Path { + ast::Path { span: dummy_sp(), global: true, idents: ids, rp: None, diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 77a8d1792dbc..91dba63a182e 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1014,7 +1014,7 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_name(ecx, ebml_w, item.ident); encode_attributes(ebml_w, item.attrs); match ty.node { - ast::ty_path(path, bounds, _) if path.idents.len() == 1 => { + ast::ty_path(ref path, bounds, _) if path.idents.len() == 1 => { assert!(bounds.is_none()); encode_impl_type_basename(ecx, ebml_w, ast_util::path_to_ident(path)); diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 59918137467a..7113244c7f6c 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -112,7 +112,7 @@ pub fn check_expr(sess: Session, "` in a constant expression"); } } - expr_path(pth) => { + expr_path(ref pth) => { // NB: In the future you might wish to relax this slightly // to handle on-demand instantiation of functions via // foo:: in a const. Currently that is only done on diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs index f6da8f392cc1..7dd7ae6ec9ae 100644 --- a/src/librustc/middle/pat_util.rs +++ b/src/librustc/middle/pat_util.rs @@ -71,10 +71,10 @@ pub fn pat_is_binding_or_wild(dm: resolve::DefMap, pat: @pat) -> bool { } pub fn pat_bindings(dm: resolve::DefMap, pat: @pat, - it: &fn(binding_mode, node_id, span, @Path)) { + it: &fn(binding_mode, node_id, span, &Path)) { for walk_pat(pat) |p| { match p.node { - pat_ident(binding_mode, pth, _) if pat_is_binding(dm, p) => { + pat_ident(binding_mode, ref pth, _) if pat_is_binding(dm, p) => { it(binding_mode, p.id, p.span, pth); } _ => {} diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 64ed3b0211d3..dd6b5615c3f3 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -276,7 +276,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, }; // Checks that a private path is in scope. - let check_path: @fn(span: span, def: def, path: @Path) = + let check_path: @fn(span: span, def: def, path: &Path) = |span, def, path| { debug!("checking path"); match def { @@ -449,7 +449,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, _ => {} } } - expr_path(path) => { + expr_path(ref path) => { check_path(expr.span, tcx.def_map.get_copy(&expr.id), path); } expr_struct(_, ref fields, _) => { diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index f65d3ad464c4..69cdbbb89771 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -784,7 +784,7 @@ fn determine_rp_in_ty(ty: @ast::Ty, // then check whether it is region-parameterized and consider // that as a direct dependency. match ty.node { - ast::ty_path(path, _bounds, id) => { + ast::ty_path(ref path, _bounds, id) => { match cx.def_map.find(&id) { Some(&ast::def_ty(did)) | Some(&ast::def_trait(did)) | @@ -820,7 +820,7 @@ fn determine_rp_in_ty(ty: @ast::Ty, visit_mt(mt, (cx, visitor)); } - ast::ty_path(path, _bounds, _) => { + ast::ty_path(ref path, _bounds, _) => { // type parameters are---for now, anyway---always invariant do cx.with_ambient_variance(rv_invariant) { for path.types.iter().advance |tp| { diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index fb9159d26bfc..8f73c8fc1730 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -1245,7 +1245,7 @@ impl Resolver { // Create the module and add all methods. match *ty { Ty { - node: ty_path(path, _, _), + node: ty_path(ref path, _, _), _ } if path.idents.len() == 1 => { let name = path_to_ident(path); @@ -1446,7 +1446,7 @@ impl Resolver { let mut module_path = ~[]; match view_path.node { - view_path_simple(_, full_path, _) => { + view_path_simple(_, ref full_path, _) => { let path_len = full_path.idents.len(); assert!(path_len != 0); @@ -1457,8 +1457,8 @@ impl Resolver { } } - view_path_glob(module_ident_path, _) | - view_path_list(module_ident_path, _, _) => { + view_path_glob(ref module_ident_path, _) | + view_path_list(ref module_ident_path, _, _) => { for module_ident_path.idents.iter().advance |ident| { module_path.push(*ident); } @@ -1468,7 +1468,7 @@ impl Resolver { // Build up the import directives. let module_ = self.get_module_from_parent(parent); match view_path.node { - view_path_simple(binding, full_path, id) => { + view_path_simple(binding, ref full_path, id) => { let source_ident = *full_path.idents.last(); let subclass = @SingleImport(binding, source_ident); @@ -3561,7 +3561,7 @@ impl Resolver { // Resolve derived traits. for traits.iter().advance |trt| { - self.resolve_trait_reference(*trt, visitor, TraitDerivation); + self.resolve_trait_reference(trt, visitor, TraitDerivation); } for (*methods).iter().advance |method| { @@ -4117,7 +4117,7 @@ impl Resolver { // Like path expressions, the interpretation of path types depends // on whether the path has multiple elements in it or not. - ty_path(path, bounds, path_id) => { + ty_path(ref path, bounds, path_id) => { // This is a path in the type namespace. Walk through scopes // scopes looking for it. let mut result_def = None; @@ -4211,7 +4211,7 @@ impl Resolver { let pat_id = pattern.id; for walk_pat(pattern) |pattern| { match pattern.node { - pat_ident(binding_mode, path, _) + pat_ident(binding_mode, ref path, _) if !path.global && path.idents.len() == 1 => { // The meaning of pat_ident with no type parameters @@ -4338,7 +4338,7 @@ impl Resolver { } } - pat_ident(binding_mode, path, _) => { + pat_ident(binding_mode, ref path, _) => { // This must be an enum variant, struct, or constant. match self.resolve_path(path, ValueNS, false, visitor) { Some(def @ def_variant(*)) | @@ -4371,7 +4371,7 @@ impl Resolver { } } - pat_enum(path, _) => { + pat_enum(ref path, _) => { // This must be an enum variant, struct or const. match self.resolve_path(path, ValueNS, false, visitor) { Some(def @ def_fn(*)) | @@ -4409,7 +4409,7 @@ impl Resolver { self.resolve_expr(last_expr, visitor); } - pat_struct(path, _, _) => { + pat_struct(ref path, _, _) => { match self.resolve_path(path, TypeNS, false, visitor) { Some(def_ty(class_id)) if self.structs.contains(&class_id) => { @@ -4484,7 +4484,7 @@ impl Resolver { /// If `check_ribs` is true, checks the local definitions first; i.e. /// doesn't skip straight to the containing module. pub fn resolve_path(@mut self, - path: @Path, + path: &Path, namespace: Namespace, check_ribs: bool, visitor: ResolveVisitor) @@ -4610,7 +4610,7 @@ impl Resolver { return NoNameDefinition; } - pub fn intern_module_part_of_path(@mut self, path: @Path) -> ~[ident] { + pub fn intern_module_part_of_path(@mut self, path: &Path) -> ~[ident] { let mut module_path_idents = ~[]; for path.idents.iter().enumerate().advance |(index, ident)| { if index == path.idents.len() - 1 { @@ -4624,7 +4624,7 @@ impl Resolver { } pub fn resolve_module_relative_path(@mut self, - path: @Path, + path: &Path, xray: XrayFlag, namespace: Namespace) -> Option { @@ -4690,7 +4690,7 @@ impl Resolver { /// Invariant: This must be called only during main resolution, not during /// import resolution. pub fn resolve_crate_relative_path(@mut self, - path: @Path, + path: &Path, xray: XrayFlag, namespace: Namespace) -> Option { @@ -4916,7 +4916,7 @@ impl Resolver { // The interpretation of paths depends on whether the path has // multiple elements in it or not. - expr_path(path) => { + expr_path(ref path) => { // This is a local path in the value namespace. Walk through // scopes looking for it. @@ -4985,7 +4985,7 @@ impl Resolver { visitor); } - expr_struct(path, _, _) => { + expr_struct(ref path, _, _) => { // Resolve the path to the structure it goes to. match self.resolve_path(path, TypeNS, false, visitor) { Some(def_ty(class_id)) | Some(def_struct(class_id)) diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 1d69b20f5c44..3e828a891d49 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -385,7 +385,7 @@ pub fn expand_nested_bindings<'r>(bcx: block, do m.map |br| { match br.pats[col].node { - ast::pat_ident(_, path, Some(inner)) => { + ast::pat_ident(_, ref path, Some(inner)) => { let pats = vec::append( br.pats.slice(0u, col).to_owned(), vec::append(~[inner], @@ -441,7 +441,7 @@ pub fn enter_match<'r>(bcx: block, let this = br.pats[col]; match this.node { - ast::pat_ident(_, path, None) => { + ast::pat_ident(_, ref path, None) => { if pat_is_binding(dm, this) { let binding_info = br.data.bindings_map.get( diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index d6105cc1dded..e5edd43cf051 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1399,7 +1399,7 @@ pub fn alloc_local(cx: block, local: &ast::local) -> block { let _icx = push_ctxt("alloc_local"); let t = node_id_type(cx, local.node.id); let simple_name = match local.node.pat.node { - ast::pat_ident(_, pth, None) => Some(path_to_ident(pth)), + ast::pat_ident(_, ref pth, None) => Some(path_to_ident(pth)), _ => None }; let val = alloc_ty(cx, t); diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index 9566f41a45fd..bbec78880fe2 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -525,7 +525,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: &ast::expr) -> ValueRef { _ => cx.sess.span_bug(e.span, "bad const-slice expr") } } - ast::expr_path(pth) => { + ast::expr_path(ref pth) => { assert_eq!(pth.types.len(), 0); let tcx = cx.tcx; match tcx.def_map.find(&e.id) { diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index ac5eb6b067c9..32a71ea70197 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -133,7 +133,7 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { let cx = bcx.ccx(); let ident = match local.node.pat.node { - ast::pat_ident(_, pth, _) => ast_util::path_to_ident(pth), + ast::pat_ident(_, ref pth, _) => ast_util::path_to_ident(pth), // FIXME this should be handled (#2533) _ => { bcx.sess().span_note(local.span, "debuginfo for pattern bindings NYI"); @@ -204,7 +204,7 @@ pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { let context = create_function(fcx); match arg.pat.node { - ast::pat_ident(_, path, _) => { + ast::pat_ident(_, ref path, _) => { // XXX: This is wrong; it should work for multiple bindings. let ident = path.idents.last(); let name: &str = cx.sess.str_of(*ident); diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 4d2849c52105..1cab6607077d 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -136,7 +136,7 @@ fn ast_path_substs( def_id: ast::def_id, decl_generics: &ty::Generics, self_ty: Option, - path: @ast::Path) -> ty::substs + path: &ast::Path) -> ty::substs { /*! * @@ -188,7 +188,7 @@ pub fn ast_path_to_substs_and_ty( this: &AC, rscope: &RS, did: ast::def_id, - path: @ast::Path) -> ty_param_substs_and_ty + path: &ast::Path) -> ty_param_substs_and_ty { let tcx = this.tcx(); let ty::ty_param_bounds_and_ty { @@ -206,7 +206,7 @@ pub fn ast_path_to_trait_ref( rscope: &RS, trait_def_id: ast::def_id, self_ty: Option, - path: @ast::Path) -> @ty::TraitRef + path: &ast::Path) -> @ty::TraitRef { let trait_def = this.get_trait_def(trait_def_id); @@ -228,7 +228,7 @@ pub fn ast_path_to_ty( this: &AC, rscope: &RS, did: ast::def_id, - path: @ast::Path) + path: &ast::Path) -> ty_param_substs_and_ty { // Look up the polytype of the item and then substitute the provided types @@ -276,7 +276,7 @@ pub fn ast_ty_to_ty( } return ty::mk_evec(tcx, mt, vst); } - ast::ty_path(path, bounds, id) => { + ast::ty_path(ref path, bounds, id) => { // Note that the "bounds must be empty if path is not a trait" // restriction is enforced in the below case for ty_path, which // will run after this as long as the path isn't a trait. @@ -321,7 +321,7 @@ pub fn ast_ty_to_ty( } fn check_path_args(tcx: ty::ctxt, - path: @ast::Path, + path: &ast::Path, flags: uint) { if (flags & NO_TPS) != 0u { if path.types.len() > 0u { @@ -405,7 +405,7 @@ pub fn ast_ty_to_ty( ast_ty.span); ty::mk_closure(tcx, fn_decl) } - ast::ty_path(path, bounds, id) => { + ast::ty_path(ref path, bounds, id) => { let a_def = match tcx.def_map.find(&id) { None => tcx.sess.span_fatal( ast_ty.span, fmt!("unbound path %s", diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs index 45867ae77e08..1f7946576db5 100644 --- a/src/librustc/middle/typeck/check/_match.rs +++ b/src/librustc/middle/typeck/check/_match.rs @@ -105,7 +105,7 @@ pub struct pat_ctxt { map: PatIdMap, } -pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: @ast::Path, +pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: &ast::Path, subpats: &Option<~[@ast::pat]>, expected: ty::t) { // Typecheck the path. @@ -271,7 +271,7 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: @ast::Path, /// `etc` is true if the pattern said '...' and false otherwise. pub fn check_struct_pat_fields(pcx: &pat_ctxt, span: span, - path: @ast::Path, + path: &ast::Path, fields: &[ast::field_pat], class_fields: ~[ty::field_ty], class_id: ast::def_id, @@ -322,7 +322,7 @@ pub fn check_struct_pat_fields(pcx: &pat_ctxt, } pub fn check_struct_pat(pcx: &pat_ctxt, pat_id: ast::node_id, span: span, - expected: ty::t, path: @ast::Path, + expected: ty::t, path: &ast::Path, fields: &[ast::field_pat], etc: bool, class_id: ast::def_id, substitutions: &ty::substs) { let fcx = pcx.fcx; @@ -356,7 +356,7 @@ pub fn check_struct_like_enum_variant_pat(pcx: &pat_ctxt, pat_id: ast::node_id, span: span, expected: ty::t, - path: @ast::Path, + path: &ast::Path, fields: &[ast::field_pat], etc: bool, enum_id: ast::def_id, @@ -440,7 +440,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) { demand::suptype(fcx, pat.span, expected, const_tpt.ty); fcx.write_ty(pat.id, const_tpt.ty); } - ast::pat_ident(bm, name, sub) if pat_is_binding(tcx.def_map, pat) => { + ast::pat_ident(bm, ref name, sub) if pat_is_binding(tcx.def_map, pat) => { let typ = fcx.local_ty(pat.span, pat.id); match bm { @@ -476,13 +476,13 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) { _ => () } } - ast::pat_ident(_, path, _) => { + ast::pat_ident(_, ref path, _) => { check_pat_variant(pcx, pat, path, &Some(~[]), expected); } - ast::pat_enum(path, ref subpats) => { + ast::pat_enum(ref path, ref subpats) => { check_pat_variant(pcx, pat, path, subpats, expected); } - ast::pat_struct(path, ref fields, etc) => { + ast::pat_struct(ref path, ref fields, etc) => { // Grab the class data that we care about. let structure = structure_of(fcx, pat.span, expected); let mut error_happened = false; diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 00ebca5abc14..f595b2dfc6a0 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -489,7 +489,7 @@ pub fn check_fn(ccx: @mut CrateCtxt, // Add pattern bindings. let visit_pat: @fn(@ast::pat, ((), visit::vt<()>)) = |p, (e, v)| { match p.node { - ast::pat_ident(_, path, _) + ast::pat_ident(_, ref path, _) if pat_util::pat_is_binding(fcx.ccx.tcx.def_map, p) => { assign(p.id, None); debug!("Pattern binding %s is assigned to %s", @@ -2437,7 +2437,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, }; fcx.write_ty(id, oprnd_t); } - ast::expr_path(pth) => { + ast::expr_path(ref pth) => { let defn = lookup_def(fcx, pth.span, id); let tpt = ty_param_bounds_and_ty_for_def(fcx, expr.span, defn); @@ -2775,7 +2775,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, fcx.write_ty(id, typ); } } - ast::expr_struct(path, ref fields, base_expr) => { + ast::expr_struct(ref path, ref fields, base_expr) => { // Resolve the path. match tcx.def_map.find(&id) { Some(&ast::def_struct(type_def_id)) => { @@ -3286,7 +3286,7 @@ pub fn ty_param_bounds_and_ty_for_def(fcx: @mut FnCtxt, // Instantiates the given path, which must refer to an item with the given // number of type parameters and type. pub fn instantiate_path(fcx: @mut FnCtxt, - pth: @ast::Path, + pth: &ast::Path, tpt: ty_param_bounds_and_ty, span: span, node_id: ast::node_id) { diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index de05aca61caf..b642eff12a8d 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -671,7 +671,7 @@ pub fn check_methods_against_trait(ccx: &CrateCtxt, impl_m.span, fmt!("method `%s` is not a member of trait `%s`", tcx.sess.str_of(impl_m.mty.ident), - path_to_str(a_trait_ty.path, tcx.sess.intr()))); + path_to_str(&a_trait_ty.path, tcx.sess.intr()))); } } } @@ -966,7 +966,7 @@ pub fn instantiate_trait_ref(ccx: &CrateCtxt, ast::def_trait(trait_did) => { let trait_ref = astconv::ast_path_to_trait_ref( - ccx, &rscope, trait_did, Some(self_ty), ast_trait_ref.path); + ccx, &rscope, trait_did, Some(self_ty), &ast_trait_ref.path); ccx.tcx.trait_refs.insert( ast_trait_ref.ref_id, trait_ref); return trait_ref; @@ -975,7 +975,7 @@ pub fn instantiate_trait_ref(ccx: &CrateCtxt, ccx.tcx.sess.span_fatal( ast_trait_ref.path.span, fmt!("%s is not a trait", - path_to_str(ast_trait_ref.path, + path_to_str(&ast_trait_ref.path, ccx.tcx.sess.intr()))); } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index ffbd61b15edd..d053c203b91a 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -255,10 +255,10 @@ pub enum pat_ { // which it is. The resolver determines this, and // records this pattern's node_id in an auxiliary // set (of "pat_idents that refer to nullary enums") - pat_ident(binding_mode, @Path, Option<@pat>), - pat_enum(@Path, Option<~[@pat]>), /* "none" means a * pattern where + pat_ident(binding_mode, Path, Option<@pat>), + pat_enum(Path, Option<~[@pat]>), /* "none" means a * pattern where * we don't bind the fields to names */ - pat_struct(@Path, ~[field_pat], bool), + pat_struct(Path, ~[field_pat], bool), pat_tup(~[@pat]), pat_box(@pat), pat_uniq(@pat), @@ -456,7 +456,7 @@ pub enum expr_ { expr_assign_op(node_id, binop, @expr, @expr), expr_field(@expr, ident, ~[@Ty]), expr_index(node_id, @expr, @expr), - expr_path(@Path), + expr_path(Path), /// The special identifier `self`. expr_self, @@ -471,7 +471,7 @@ pub enum expr_ { expr_mac(mac), // A struct literal expression. - expr_struct(@Path, ~[field], Option<@expr>), + expr_struct(Path, ~[field], Option<@expr>), // A vector literal constructed from one repeated element. expr_repeat(@expr /* element */, @expr /* count */, mutability), @@ -583,7 +583,7 @@ pub type mac = spanned; #[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum mac_ { - mac_invoc_tt(@Path,~[token_tree]), // new macro-invocation + mac_invoc_tt(Path,~[token_tree]), // new macro-invocation } pub type lit = spanned; @@ -734,7 +734,7 @@ pub enum ty_ { ty_closure(@TyClosure), ty_bare_fn(@TyBareFn), ty_tup(~[@Ty]), - ty_path(@Path, @Option>, node_id), // for #7264; see above + ty_path(Path, @Option>, node_id), // for #7264; see above ty_mac(mac), // ty_infer means the type should be inferred instead of it having been // specified. This should only appear at the "top level" of a type and not @@ -890,13 +890,13 @@ pub enum view_path_ { // or just // // foo::bar::baz (with 'baz =' implicitly on the left) - view_path_simple(ident, @Path, node_id), + view_path_simple(ident, Path, node_id), // foo::bar::* - view_path_glob(@Path, node_id), + view_path_glob(Path, node_id), // foo::bar::{a,b,c} - view_path_list(@Path, ~[path_list_ident], node_id) + view_path_list(Path, ~[path_list_ident], node_id) } #[deriving(Eq, Encodable, Decodable,IterBytes)] @@ -939,7 +939,7 @@ pub struct attribute_ { */ #[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct trait_ref { - path: @Path, + path: Path, ref_id: node_id, } diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index 3abbe3970540..59020e9d1837 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -196,7 +196,7 @@ pub fn map_block(b: &blk, (cx,v): (@mut Ctx, visit::vt<@mut Ctx>)) { pub fn map_pat(pat: @pat, (cx,v): (@mut Ctx, visit::vt<@mut Ctx>)) { match pat.node { - pat_ident(_, path, _) => { + pat_ident(_, ref path, _) => { // Note: this is at least *potentially* a pattern... cx.map.insert(pat.id, node_local(ast_util::path_to_ident(path))); } diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index ce8e24fd4445..35f9782f694f 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -27,7 +27,7 @@ pub fn path_name_i(idents: &[ident]) -> ~str { idents.map(|i| token::interner_get(i.name)).connect("::") } -pub fn path_to_ident(p: @Path) -> ident { copy *p.idents.last() } +pub fn path_to_ident(p: &Path) -> ident { copy *p.idents.last() } pub fn local_def(id: node_id) -> def_id { ast::def_id { crate: local_crate, node: id } @@ -212,8 +212,8 @@ pub fn default_block( } } -pub fn ident_to_path(s: span, i: ident) -> @Path { - @ast::Path { span: s, +pub fn ident_to_path(s: span, i: ident) -> Path { + ast::Path { span: s, global: false, idents: ~[i], rp: None, diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index ad14b567b960..568688749161 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -326,7 +326,7 @@ pub fn expr_to_ident(cx: @ExtCtxt, expr: @ast::expr, err_msg: &str) -> ast::ident { match expr.node { - ast::expr_path(p) => { + ast::expr_path(ref p) => { if p.types.len() > 0u || p.idents.len() != 1u { cx.span_fatal(expr.span, err_msg); } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index e2b8ff3c0302..c933caa16c4c 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -32,21 +32,21 @@ mod syntax { pub trait AstBuilder { // paths - fn path(&self, span: span, strs: ~[ast::ident]) -> @ast::Path; - fn path_ident(&self, span: span, id: ast::ident) -> @ast::Path; - fn path_global(&self, span: span, strs: ~[ast::ident]) -> @ast::Path; + fn path(&self, span: span, strs: ~[ast::ident]) -> ast::Path; + fn path_ident(&self, span: span, id: ast::ident) -> ast::Path; + fn path_global(&self, span: span, strs: ~[ast::ident]) -> ast::Path; fn path_all(&self, sp: span, global: bool, idents: ~[ast::ident], rp: Option<@ast::Lifetime>, types: ~[@ast::Ty]) - -> @ast::Path; + -> ast::Path; // types fn ty_mt(&self, ty: @ast::Ty, mutbl: ast::mutability) -> ast::mt; fn ty(&self, span: span, ty: ast::ty_) -> @ast::Ty; - fn ty_path(&self, @ast::Path, @Option>) -> @ast::Ty; + fn ty_path(&self, ast::Path, @Option>) -> @ast::Ty; fn ty_ident(&self, span: span, idents: ast::ident) -> @ast::Ty; fn ty_rptr(&self, span: span, @@ -68,8 +68,8 @@ pub trait AstBuilder { fn typaram(&self, id: ast::ident, bounds: @OptVec) -> ast::TyParam; - fn trait_ref(&self, path: @ast::Path) -> @ast::trait_ref; - fn typarambound(&self, path: @ast::Path) -> ast::TyParamBound; + fn trait_ref(&self, path: ast::Path) -> @ast::trait_ref; + fn typarambound(&self, path: ast::Path) -> ast::TyParamBound; fn lifetime(&self, span: span, ident: ast::ident) -> ast::Lifetime; // statements @@ -86,7 +86,7 @@ pub trait AstBuilder { // expressions fn expr(&self, span: span, node: ast::expr_) -> @ast::expr; - fn expr_path(&self, path: @ast::Path) -> @ast::expr; + fn expr_path(&self, path: ast::Path) -> @ast::expr; fn expr_ident(&self, span: span, id: ast::ident) -> @ast::expr; fn expr_self(&self, span: span) -> @ast::expr; @@ -110,7 +110,7 @@ pub trait AstBuilder { fn expr_blk(&self, b: ast::blk) -> @ast::expr; fn field_imm(&self, span: span, name: ident, e: @ast::expr) -> ast::field; - fn expr_struct(&self, span: span, path: @ast::Path, fields: ~[ast::field]) -> @ast::expr; + fn expr_struct(&self, span: span, path: ast::Path, fields: ~[ast::field]) -> @ast::expr; fn expr_struct_ident(&self, span: span, id: ast::ident, fields: ~[ast::field]) -> @ast::expr; fn expr_lit(&self, sp: span, lit: ast::lit_) -> @ast::expr; @@ -138,9 +138,9 @@ pub trait AstBuilder { span: span, ident: ast::ident, bm: ast::binding_mode) -> @ast::pat; - fn pat_enum(&self, span: span, path: @ast::Path, subpats: ~[@ast::pat]) -> @ast::pat; + fn pat_enum(&self, span: span, path: ast::Path, subpats: ~[@ast::pat]) -> @ast::pat; fn pat_struct(&self, span: span, - path: @ast::Path, field_pats: ~[ast::field_pat]) -> @ast::pat; + path: ast::Path, field_pats: ~[ast::field_pat]) -> @ast::pat; fn arm(&self, span: span, pats: ~[@ast::pat], expr: @ast::expr) -> ast::arm; fn arm_unreachable(&self, span: span) -> ast::arm; @@ -226,13 +226,13 @@ pub trait AstBuilder { } impl AstBuilder for @ExtCtxt { - fn path(&self, span: span, strs: ~[ast::ident]) -> @ast::Path { + fn path(&self, span: span, strs: ~[ast::ident]) -> ast::Path { self.path_all(span, false, strs, None, ~[]) } - fn path_ident(&self, span: span, id: ast::ident) -> @ast::Path { + fn path_ident(&self, span: span, id: ast::ident) -> ast::Path { self.path(span, ~[id]) } - fn path_global(&self, span: span, strs: ~[ast::ident]) -> @ast::Path { + fn path_global(&self, span: span, strs: ~[ast::ident]) -> ast::Path { self.path_all(span, true, strs, None, ~[]) } fn path_all(&self, sp: span, @@ -240,8 +240,8 @@ impl AstBuilder for @ExtCtxt { idents: ~[ast::ident], rp: Option<@ast::Lifetime>, types: ~[@ast::Ty]) - -> @ast::Path { - @ast::Path { + -> ast::Path { + ast::Path { span: sp, global: global, idents: idents, @@ -265,7 +265,7 @@ impl AstBuilder for @ExtCtxt { } } - fn ty_path(&self, path: @ast::Path, bounds: @Option>) + fn ty_path(&self, path: ast::Path, bounds: @Option>) -> @ast::Ty { self.ty(path.span, ast::ty_path(path, bounds, self.next_id())) @@ -358,14 +358,14 @@ impl AstBuilder for @ExtCtxt { } } - fn trait_ref(&self, path: @ast::Path) -> @ast::trait_ref { + fn trait_ref(&self, path: ast::Path) -> @ast::trait_ref { @ast::trait_ref { path: path, ref_id: self.next_id() } } - fn typarambound(&self, path: @ast::Path) -> ast::TyParamBound { + fn typarambound(&self, path: ast::Path) -> ast::TyParamBound { ast::TraitTyParamBound(self.trait_ref(path)) } @@ -421,7 +421,7 @@ impl AstBuilder for @ExtCtxt { } } - fn expr_path(&self, path: @ast::Path) -> @ast::expr { + fn expr_path(&self, path: ast::Path) -> @ast::expr { self.expr(path.span, ast::expr_path(path)) } @@ -487,7 +487,7 @@ impl AstBuilder for @ExtCtxt { fn field_imm(&self, span: span, name: ident, e: @ast::expr) -> ast::field { respan(span, ast::field_ { ident: name, expr: e }) } - fn expr_struct(&self, span: span, path: @ast::Path, fields: ~[ast::field]) -> @ast::expr { + fn expr_struct(&self, span: span, path: ast::Path, fields: ~[ast::field]) -> @ast::expr { self.expr(span, ast::expr_struct(path, fields, None)) } fn expr_struct_ident(&self, span: span, @@ -570,12 +570,12 @@ impl AstBuilder for @ExtCtxt { let pat = ast::pat_ident(bm, path, None); self.pat(span, pat) } - fn pat_enum(&self, span: span, path: @ast::Path, subpats: ~[@ast::pat]) -> @ast::pat { + fn pat_enum(&self, span: span, path: ast::Path, subpats: ~[@ast::pat]) -> @ast::pat { let pat = ast::pat_enum(path, Some(subpats)); self.pat(span, pat) } fn pat_struct(&self, span: span, - path: @ast::Path, field_pats: ~[ast::field_pat]) -> @ast::pat { + path: ast::Path, field_pats: ~[ast::field_pat]) -> @ast::pat { let pat = ast::pat_struct(path, field_pats, false); self.pat(span, pat) } diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs index 7df8874076e0..900668df117e 100644 --- a/src/libsyntax/ext/concat_idents.rs +++ b/src/libsyntax/ext/concat_idents.rs @@ -36,7 +36,7 @@ pub fn expand_syntax_ext(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree]) let e = @ast::expr { id: cx.next_id(), node: ast::expr_path( - @ast::Path { + ast::Path { span: sp, global: false, idents: ~[res], diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index 0e4fc9d96fa8..e397a4163045 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -335,7 +335,7 @@ impl<'self> TraitDef<'self> { cx.typarambound(p.to_path(cx, span, type_ident, generics)) }); // require the current trait - bounds.push(cx.typarambound(trait_path)); + bounds.push(cx.typarambound(copy trait_path)); trait_generics.ty_params.push(cx.typaram(ty_param.ident, @bounds)); } @@ -890,7 +890,7 @@ fn summarise_struct(cx: @ExtCtxt, span: span, pub fn create_subpatterns(cx: @ExtCtxt, span: span, - field_paths: ~[@ast::Path], + field_paths: ~[ast::Path], mutbl: ast::mutability) -> ~[@ast::pat] { do field_paths.map |&path| { @@ -941,7 +941,7 @@ fn create_struct_pattern(cx: @ExtCtxt, }; let path = cx.path_ident(span, cx.ident_of(fmt!("%s_%u", prefix, i))); - paths.push(path); + paths.push(copy path); ident_expr.push((opt_id, cx.expr_path(path))); } @@ -987,7 +987,7 @@ fn create_enum_variant_pattern(cx: @ExtCtxt, let path = cx.path_ident(span, cx.ident_of(fmt!("%s_%u", prefix, i))); - paths.push(path); + paths.push(copy path); ident_expr.push((None, cx.expr_path(path))); } diff --git a/src/libsyntax/ext/deriving/ty.rs b/src/libsyntax/ext/deriving/ty.rs index e210853bfb4d..4dee2e2cdb89 100644 --- a/src/libsyntax/ext/deriving/ty.rs +++ b/src/libsyntax/ext/deriving/ty.rs @@ -70,7 +70,7 @@ impl<'self> Path<'self> { span: span, self_ty: ident, self_generics: &Generics) - -> @ast::Path { + -> ast::Path { let idents = self.path.map(|s| cx.ident_of(*s) ); let lt = mk_lifetime(cx, span, &self.lifetime); let tys = self.params.map(|t| t.to_ty(cx, span, self_ty, self_generics)); @@ -162,7 +162,7 @@ impl<'self> Ty<'self> { span: span, self_ty: ident, self_generics: &Generics) - -> @ast::Path { + -> ast::Path { match *self { Self => { let self_params = do self_generics.ty_params.map |ty_param| { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 2b18ede88791..940bd5ef61c1 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -40,7 +40,7 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv, expr_mac(ref mac) => { match (*mac).node { // Token-tree macros: - mac_invoc_tt(pth, ref tts) => { + mac_invoc_tt(ref pth, ref tts) => { if (pth.idents.len() > 1u) { cx.span_fatal( pth.span, @@ -208,7 +208,7 @@ pub fn expand_item_mac(extsbox: @mut SyntaxEnv, fld: @ast_fold) -> Option<@ast::item> { let (pth, tts) = match it.node { - item_mac(codemap::spanned { node: mac_invoc_tt(pth, ref tts), _}) => { + item_mac(codemap::spanned { node: mac_invoc_tt(ref pth, ref tts), _}) => { (pth, copy *tts) } _ => cx.span_bug(it.span, "invalid item macro invocation") @@ -298,7 +298,7 @@ pub fn expand_stmt(extsbox: @mut SyntaxEnv, let (mac, pth, tts, semi) = match *s { stmt_mac(ref mac, semi) => { match mac.node { - mac_invoc_tt(pth, ref tts) => { + mac_invoc_tt(ref pth, ref tts) => { (copy *mac, pth, copy *tts, semi) } } @@ -372,10 +372,10 @@ pub fn new_name_finder() -> @Visitor<@mut ~[ast::ident]> { (ident_accum, v): (@mut ~[ast::ident], visit::vt<@mut ~[ast::ident]>)| { match *p { // we found a pat_ident! - ast::pat{id:_, node: ast::pat_ident(_,path,ref inner), span:_} => { + ast::pat{id:_, node: ast::pat_ident(_,ref path,ref inner), span:_} => { match path { // a path of length one: - @ast::Path{global: false,idents: [id], span:_,rp:_,types:_} => + &ast::Path{global: false,idents: [id], span:_,rp:_,types:_} => ident_accum.push(id), // I believe these must be enums... _ => () diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs index 1af6e7810a57..58838b0c40bd 100644 --- a/src/libsyntax/ext/pipes/ast_builder.rs +++ b/src/libsyntax/ext/pipes/ast_builder.rs @@ -25,16 +25,16 @@ mod syntax { pub use parse; } -pub fn path(ids: ~[ident], span: span) -> @ast::Path { - @ast::Path { span: span, +pub fn path(ids: ~[ident], span: span) -> ast::Path { + ast::Path { span: span, global: false, idents: ids, rp: None, types: ~[] } } -pub fn path_global(ids: ~[ident], span: span) -> @ast::Path { - @ast::Path { span: span, +pub fn path_global(ids: ~[ident], span: span) -> ast::Path { + ast::Path { span: span, global: true, idents: ids, rp: None, @@ -42,22 +42,22 @@ pub fn path_global(ids: ~[ident], span: span) -> @ast::Path { } pub trait append_types { - fn add_ty(&self, ty: @ast::Ty) -> @ast::Path; - fn add_tys(&self, tys: ~[@ast::Ty]) -> @ast::Path; + fn add_ty(&self, ty: @ast::Ty) -> ast::Path; + fn add_tys(&self, tys: ~[@ast::Ty]) -> ast::Path; } -impl append_types for @ast::Path { - fn add_ty(&self, ty: @ast::Ty) -> @ast::Path { - @ast::Path { +impl append_types for ast::Path { + fn add_ty(&self, ty: @ast::Ty) -> ast::Path { + ast::Path { types: vec::append_one(copy self.types, ty), - .. copy **self + .. copy *self } } - fn add_tys(&self, tys: ~[@ast::Ty]) -> @ast::Path { - @ast::Path { + fn add_tys(&self, tys: ~[@ast::Ty]) -> ast::Path { + ast::Path { types: vec::append(copy self.types, tys), - .. copy **self + .. copy *self } } } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index b4d64ba3e2dc..e9710c9e114d 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -33,7 +33,7 @@ pub trait ast_fold { fn fold_foreign_mod(@self, &foreign_mod) -> foreign_mod; fn fold_variant(@self, &variant) -> variant; fn fold_ident(@self, ident) -> ident; - fn fold_path(@self, @Path) -> @Path; + fn fold_path(@self, &Path) -> Path; fn fold_local(@self, @local) -> @local; fn map_exprs(@self, @fn(@expr) -> @expr, &[@expr]) -> ~[@expr]; fn new_id(@self, node_id) -> node_id; @@ -62,7 +62,7 @@ pub struct AstFoldFns { fold_foreign_mod: @fn(&foreign_mod, @ast_fold) -> foreign_mod, fold_variant: @fn(&variant_, span, @ast_fold) -> (variant_, span), fold_ident: @fn(ident, @ast_fold) -> ident, - fold_path: @fn(@Path, @ast_fold) -> Path, + fold_path: @fn(&Path, @ast_fold) -> Path, fold_local: @fn(&local_, span, @ast_fold) -> (local_, span), map_exprs: @fn(@fn(@expr) -> @expr, &[@expr]) -> ~[@expr], new_id: @fn(node_id) -> node_id, @@ -117,7 +117,7 @@ fn fold_arg_(a: arg, fld: @ast_fold) -> arg { fn fold_mac_(m: &mac, fld: @ast_fold) -> mac { spanned { node: match m.node { - mac_invoc_tt(p,ref tts) => + mac_invoc_tt(ref p,ref tts) => mac_invoc_tt(fld.fold_path(p), fold_tts(*tts,fld)) }, @@ -337,7 +337,7 @@ fn fold_struct_def(struct_def: @ast::struct_def, fld: @ast_fold) fn fold_trait_ref(p: @trait_ref, fld: @ast_fold) -> @trait_ref { @ast::trait_ref { - path: fld.fold_path(p.path), + path: fld.fold_path(&p.path), ref_id: fld.new_id(p.ref_id), } } @@ -419,7 +419,7 @@ fn noop_fold_arm(a: &arm, fld: @ast_fold) -> arm { pub fn noop_fold_pat(p: &pat_, fld: @ast_fold) -> pat_ { match *p { pat_wild => pat_wild, - pat_ident(binding_mode, pth, ref sub) => { + pat_ident(binding_mode, ref pth, ref sub) => { pat_ident( binding_mode, fld.fold_path(pth), @@ -427,13 +427,13 @@ pub fn noop_fold_pat(p: &pat_, fld: @ast_fold) -> pat_ { ) } pat_lit(e) => pat_lit(fld.fold_expr(e)), - pat_enum(pth, ref pats) => { + pat_enum(ref pth, ref pats) => { pat_enum( fld.fold_path(pth), pats.map(|pats| pats.map(|x| fld.fold_pat(*x))) ) } - pat_struct(pth, ref fields, etc) => { + pat_struct(ref pth, ref fields, etc) => { let pth_ = fld.fold_path(pth); let fs = do fields.map |f| { ast::field_pat { @@ -596,7 +596,7 @@ pub fn noop_fold_expr(e: &expr_, fld: @ast_fold) -> expr_ { fld.fold_expr(er) ) } - expr_path(pth) => expr_path(fld.fold_path(pth)), + expr_path(ref pth) => expr_path(fld.fold_path(pth)), expr_self => expr_self, expr_break(ref opt_ident) => { expr_break(opt_ident.map(|x| fld.fold_ident(*x))) @@ -621,7 +621,7 @@ pub fn noop_fold_expr(e: &expr_, fld: @ast_fold) -> expr_ { }) } expr_mac(ref mac) => expr_mac(fold_mac(mac)), - expr_struct(path, ref fields, maybe_expr) => { + expr_struct(ref path, ref fields, maybe_expr) => { expr_struct( fld.fold_path(path), fields.map(|x| fold_field(*x)), @@ -682,7 +682,7 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ { }) } ty_tup(ref tys) => ty_tup(tys.map(|ty| fld.fold_ty(*ty))), - ty_path(path, bounds, id) => + ty_path(ref path, bounds, id) => ty_path(fld.fold_path(path), @fold_opt_bounds(bounds, fld), fld.new_id(id)), ty_fixed_length_vec(ref mt, e) => { ty_fixed_length_vec( @@ -754,7 +754,7 @@ fn noop_fold_ident(i: ident, _fld: @ast_fold) -> ident { /* FIXME (#2543) */ copy i } -fn noop_fold_path(p: @Path, fld: @ast_fold) -> Path { +fn noop_fold_path(p: &Path, fld: @ast_fold) -> Path { ast::Path { span: fld.new_span(p.span), global: p.global, @@ -907,8 +907,8 @@ impl ast_fold for AstFoldFns { fn fold_ident(@self, x: ident) -> ident { (self.fold_ident)(x, self as @ast_fold) } - fn fold_path(@self, x: @Path) -> @Path { - @(self.fold_path)(x, self as @ast_fold) + fn fold_path(@self, x: &Path) -> Path { + (self.fold_path)(x, self as @ast_fold) } fn fold_local(@self, x: @local) -> @local { let (n, s) = (self.fold_local)(&x.node, x.span, self as @ast_fold); diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 6dd8d4880e3f..634efbe165da 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -366,7 +366,7 @@ mod test { #[test] fn path_exprs_1 () { assert_eq!(string_to_expr(@"a"), @ast::expr{id:1, - node:ast::expr_path(@ast::Path {span:sp(0,1), + node:ast::expr_path(ast::Path {span:sp(0,1), global:false, idents:~[str_to_ident("a")], rp:None, @@ -378,7 +378,7 @@ mod test { assert_eq!(string_to_expr(@"::a::b"), @ast::expr{id:1, node:ast::expr_path( - @ast::Path {span:sp(0,6), + ast::Path {span:sp(0,6), global:true, idents:strs_to_idents(~["a","b"]), rp:None, @@ -428,7 +428,7 @@ mod test { node:ast::expr_ret( Some(@ast::expr{id:1, node:ast::expr_path( - @ast::Path{span:sp(7,8), + ast::Path{span:sp(7,8), global:false, idents:~[str_to_ident("d")], rp:None, @@ -444,7 +444,7 @@ mod test { node: ast::stmt_expr(@ast::expr{ id: 1, node: ast::expr_path( - @ast::Path{ + ast::Path{ span:sp(0,1), global:false, idents:~[str_to_ident("b")], @@ -465,7 +465,7 @@ mod test { assert_eq!(parser.parse_pat(), @ast::pat{id:1, // fixme node: ast::pat_ident(ast::bind_infer, - @ast::Path{ + ast::Path{ span:sp(0,1), global:false, idents:~[str_to_ident("b")], @@ -483,7 +483,7 @@ mod test { ast::arg{ is_mutbl: false, ty: @ast::Ty{id:3, // fixme - node: ast::ty_path(@ast::Path{ + node: ast::ty_path(ast::Path{ span:sp(4,4), // this is bizarre... // check this in the original parser? global:false, @@ -494,7 +494,7 @@ mod test { span:sp(4,7)}, pat: @ast::pat{id:1, node: ast::pat_ident(ast::bind_infer, - @ast::Path{ + ast::Path{ span:sp(0,1), global:false, idents:~[str_to_ident("b")], @@ -520,7 +520,7 @@ mod test { inputs: ~[ast::arg{ is_mutbl: false, ty: @ast::Ty{id:3, // fixme - node: ast::ty_path(@ast::Path{ + node: ast::ty_path(ast::Path{ span:sp(10,13), global:false, idents:~[str_to_ident("int")], @@ -531,7 +531,7 @@ mod test { pat: @ast::pat{id:1, // fixme node: ast::pat_ident( ast::bind_infer, - @ast::Path{ + ast::Path{ span:sp(6,7), global:false, idents:~[str_to_ident("b")], @@ -561,7 +561,7 @@ mod test { node: ast::stmt_semi(@ast::expr{ id: 6, node: ast::expr_path( - @ast::Path{ + ast::Path{ span:sp(17,18), global:false, idents:~[str_to_ident("b")], diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 35c558c52962..00386f611b14 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -130,20 +130,28 @@ The important thing is to make sure that lookahead doesn't balk at INTERPOLATED tokens */ macro_rules! maybe_whole_expr ( ($p:expr) => ( - match *($p).token { - INTERPOLATED(token::nt_expr(e)) => { - $p.bump(); - return e; + { + // This horrible convolution is brought to you by + // @mut, have a terrible day + let ret = match *($p).token { + INTERPOLATED(token::nt_expr(e)) => { + Some(e) + } + INTERPOLATED(token::nt_path(ref pt)) => { + Some($p.mk_expr( + ($p).span.lo, + ($p).span.hi, + expr_path(/* bad */ copy *pt))) + } + _ => None + }; + match ret { + Some(e) => { + $p.bump(); + return e; + } + None => () } - INTERPOLATED(token::nt_path(pt)) => { - $p.bump(); - return $p.mk_expr( - ($p).span.lo, - ($p).span.hi, - expr_path(pt) - ); - } - _ => () } ) ) @@ -1218,10 +1226,10 @@ impl Parser { } // parse a path that doesn't have type parameters attached - pub fn parse_path_without_tps(&self) -> @ast::Path { + pub fn parse_path_without_tps(&self) -> ast::Path { maybe_whole!(self, nt_path); let (ids,is_global,sp) = self.parse_path(); - @ast::Path { span: sp, + ast::Path { span: sp, global: is_global, idents: ids, rp: None, @@ -1229,7 +1237,7 @@ impl Parser { } pub fn parse_bounded_path_with_tps(&self, colons: bool, - before_tps: Option<&fn()>) -> @ast::Path { + before_tps: Option<&fn()>) -> ast::Path { debug!("parse_path_with_tps(colons=%b)", colons); maybe_whole!(self, nt_path); @@ -1288,22 +1296,22 @@ impl Parser { } }; - @ast::Path { span: mk_sp(lo, hi), + ast::Path { span: mk_sp(lo, hi), rp: rp, types: tps, - .. copy *path } + .. path } } // parse a path optionally with type parameters. If 'colons' // is true, then type parameters must be preceded by colons, // as in a::t:: - pub fn parse_path_with_tps(&self, colons: bool) -> @ast::Path { + pub fn parse_path_with_tps(&self, colons: bool) -> ast::Path { self.parse_bounded_path_with_tps(colons, None) } // Like the above, but can also parse kind bounds in the case of a // path to be used as a type that might be a trait. - pub fn parse_type_path(&self) -> (@ast::Path, Option>) { + pub fn parse_type_path(&self) -> (ast::Path, Option>) { let mut bounds = None; let path = self.parse_bounded_path_with_tps(false, Some(|| { // Note: this closure might not even get called in the case of a @@ -3557,9 +3565,9 @@ impl Parser { let opt_trait = if could_be_trait && self.eat_keyword(keywords::For) { // New-style trait. Reinterpret the type as a trait. let opt_trait_ref = match ty.node { - ty_path(path, @None, node_id) => { + ty_path(ref path, @None, node_id) => { Some(@trait_ref { - path: path, + path: /* bad */ copy *path, ref_id: node_id }) } @@ -4558,7 +4566,7 @@ impl Parser { let id = self.parse_ident(); path.push(id); } - let path = @ast::Path { span: mk_sp(lo, self.span.hi), + let path = ast::Path { span: mk_sp(lo, self.span.hi), global: false, idents: path, rp: None, @@ -4588,7 +4596,7 @@ impl Parser { seq_sep_trailing_allowed(token::COMMA), |p| p.parse_path_list_ident() ); - let path = @ast::Path { span: mk_sp(lo, self.span.hi), + let path = ast::Path { span: mk_sp(lo, self.span.hi), global: false, idents: path, rp: None, @@ -4600,7 +4608,7 @@ impl Parser { // foo::bar::* token::BINOP(token::STAR) => { self.bump(); - let path = @ast::Path { span: mk_sp(lo, self.span.hi), + let path = ast::Path { span: mk_sp(lo, self.span.hi), global: false, idents: path, rp: None, @@ -4616,7 +4624,7 @@ impl Parser { _ => () } let last = path[path.len() - 1u]; - let path = @ast::Path { span: mk_sp(lo, self.span.hi), + let path = ast::Path { span: mk_sp(lo, self.span.hi), global: false, idents: path, rp: None, diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index a50fa4168320..0264903076b9 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -106,7 +106,7 @@ pub enum nonterminal { nt_expr(@ast::expr), nt_ty( @ast::Ty), nt_ident(ast::ident, bool), - nt_path(@ast::Path), + nt_path( ast::Path), nt_tt( @ast::token_tree), //needs @ed to break a circularity nt_matchers(~[ast::matcher]) } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index f6d62e476108..36e9ba4b08a2 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -179,7 +179,7 @@ pub fn generics_to_str(generics: &ast::Generics, to_str(generics, print_generics, intr) } -pub fn path_to_str(p: @ast::Path, intr: @ident_interner) -> ~str { +pub fn path_to_str(p: &ast::Path, intr: @ident_interner) -> ~str { to_str(p, |a,b| print_path(a, b, false), intr) } @@ -419,7 +419,7 @@ pub fn print_type(s: @ps, ty: @ast::Ty) { f.purity, f.onceness, &f.decl, None, &f.bounds, Some(&generics), None); } - ast::ty_path(path, bounds, _) => print_bounded_path(s, path, bounds), + ast::ty_path(ref path, bounds, _) => print_bounded_path(s, path, bounds), ast::ty_fixed_length_vec(ref mt, v) => { word(s.s, "["); match mt.mutbl { @@ -600,7 +600,7 @@ pub fn print_item(s: @ps, item: @ast::item) { if i != 0 { word_space(s, "+"); } - print_path(s, trait_.path, false); + print_path(s, &trait_.path, false); } } word(s.s, " "); @@ -610,7 +610,7 @@ pub fn print_item(s: @ps, item: @ast::item) { } bclose(s, item.span); } - ast::item_mac(codemap::spanned { node: ast::mac_invoc_tt(pth, ref tts), + ast::item_mac(codemap::spanned { node: ast::mac_invoc_tt(ref pth, ref tts), _}) => { print_visibility(s, item.vis); print_path(s, pth, false); @@ -627,7 +627,7 @@ pub fn print_item(s: @ps, item: @ast::item) { } fn print_trait_ref(s: @ps, t: &ast::trait_ref) { - print_path(s, t.path, false); + print_path(s, &t.path, false); } pub fn print_enum_def(s: @ps, enum_definition: &ast::enum_def, @@ -1005,7 +1005,7 @@ pub fn print_if(s: @ps, test: @ast::expr, blk: &ast::blk, pub fn print_mac(s: @ps, m: &ast::mac) { match m.node { - ast::mac_invoc_tt(pth, ref tts) => { + ast::mac_invoc_tt(ref pth, ref tts) => { print_path(s, pth, false); word(s.s, "!"); popen(s); @@ -1134,7 +1134,7 @@ pub fn print_expr(s: @ps, expr: @ast::expr) { end(s); } - ast::expr_struct(path, ref fields, wth) => { + ast::expr_struct(ref path, ref fields, wth) => { print_path(s, path, true); word(s.s, "{"); commasep_cmnt(s, consistent, (*fields), print_field, get_span); @@ -1359,7 +1359,7 @@ pub fn print_expr(s: @ps, expr: @ast::expr) { print_expr(s, index); word(s.s, "]"); } - ast::expr_path(path) => print_path(s, path, true), + ast::expr_path(ref path) => print_path(s, path, true), ast::expr_self => word(s.s, "self"), ast::expr_break(opt_ident) => { word(s.s, "break"); @@ -1486,7 +1486,7 @@ pub fn print_for_decl(s: @ps, loc: @ast::local, coll: @ast::expr) { print_expr(s, coll); } -fn print_path_(s: @ps, path: @ast::Path, colons_before_params: bool, +fn print_path_(s: @ps, path: &ast::Path, colons_before_params: bool, opt_bounds: &Option>) { maybe_print_comment(s, path.span.lo); if path.global { word(s.s, "::"); } @@ -1518,11 +1518,11 @@ fn print_path_(s: @ps, path: @ast::Path, colons_before_params: bool, } } -pub fn print_path(s: @ps, path: @ast::Path, colons_before_params: bool) { +pub fn print_path(s: @ps, path: &ast::Path, colons_before_params: bool) { print_path_(s, path, colons_before_params, &None) } -pub fn print_bounded_path(s: @ps, path: @ast::Path, +pub fn print_bounded_path(s: @ps, path: &ast::Path, bounds: &Option>) { print_path_(s, path, false, bounds) } @@ -1543,7 +1543,7 @@ pub fn print_pat(s: @ps, pat: @ast::pat, refutable: bool) { is that it doesn't matter */ match pat.node { ast::pat_wild => word(s.s, "_"), - ast::pat_ident(binding_mode, path, sub) => { + ast::pat_ident(binding_mode, ref path, sub) => { if refutable { match binding_mode { ast::bind_by_ref(mutbl) => { @@ -1562,7 +1562,7 @@ pub fn print_pat(s: @ps, pat: @ast::pat, refutable: bool) { None => () } } - ast::pat_enum(path, ref args_) => { + ast::pat_enum(ref path, ref args_) => { print_path(s, path, true); match *args_ { None => word(s.s, "(*)"), @@ -1576,7 +1576,7 @@ pub fn print_pat(s: @ps, pat: @ast::pat, refutable: bool) { } } } - ast::pat_struct(path, ref fields, etc) => { + ast::pat_struct(ref path, ref fields, etc) => { print_path(s, path, true); word(s.s, "{"); fn print_field(s: @ps, f: ast::field_pat, refutable: bool) { @@ -1815,7 +1815,7 @@ pub fn print_meta_item(s: @ps, item: @ast::meta_item) { pub fn print_view_path(s: @ps, vp: @ast::view_path) { match vp.node { - ast::view_path_simple(ident, path, _) => { + ast::view_path_simple(ident, ref path, _) => { if path.idents[path.idents.len()-1u] != ident { print_ident(s, ident); space(s.s); @@ -1824,12 +1824,12 @@ pub fn print_view_path(s: @ps, vp: @ast::view_path) { print_path(s, path, false); } - ast::view_path_glob(path, _) => { + ast::view_path_glob(ref path, _) => { print_path(s, path, false); word(s.s, "::*"); } - ast::view_path_list(path, ref idents, _) => { + ast::view_path_list(ref path, ref idents, _) => { print_path(s, path, false); word(s.s, "::{"); do commasep(s, inconsistent, (*idents)) |s, w| { @@ -1892,7 +1892,7 @@ pub fn print_arg(s: @ps, input: ast::arg) { ast::ty_infer => print_irrefutable_pat(s, input.pat), _ => { match input.pat.node { - ast::pat_ident(_, path, _) if + ast::pat_ident(_, ref path, _) if path.idents.len() == 1 && path.idents[0] == parse::token::special_idents::invalid => { // Do nothing. diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 944e94ddc0a5..1e615ccb7775 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -139,7 +139,7 @@ pub fn visit_local(loc: &local, (e, v): (E, vt)) { } fn visit_trait_ref(tref: &ast::trait_ref, (e, v): (E, vt)) { - visit_path(tref.path, (e, v)); + visit_path(&tref.path, (e, v)); } pub fn visit_item(i: &item, (e, v): (E, vt)) { @@ -197,7 +197,7 @@ pub fn visit_item(i: &item, (e, v): (E, vt)) { } item_trait(ref generics, ref traits, ref methods) => { (v.visit_generics)(generics, (copy e, v)); - for traits.iter().advance |p| { visit_path(p.path, (copy e, v)); } + for traits.iter().advance |p| { visit_path(&p.path, (copy e, v)); } for methods.iter().advance |m| { (v.visit_trait_method)(m, (copy e, v)); } @@ -252,7 +252,7 @@ pub fn visit_ty(t: &Ty, (e, v): (E, vt)) { for f.decl.inputs.iter().advance |a| { (v.visit_ty)(a.ty, (copy e, v)); } (v.visit_ty)(f.decl.output, (e, v)); }, - ty_path(p, bounds, _) => { + ty_path(ref p, bounds, _) => { visit_path(p, (copy e, v)); do bounds.map |bounds| { visit_ty_param_bounds(bounds, (copy e, v)); @@ -272,7 +272,7 @@ pub fn visit_path(p: &Path, (e, v): (E, vt)) { pub fn visit_pat(p: &pat, (e, v): (E, vt)) { match p.node { - pat_enum(path, ref children) => { + pat_enum(ref path, ref children) => { visit_path(path, (copy e, v)); for children.iter().advance |children| { for children.iter().advance |child| { @@ -280,7 +280,7 @@ pub fn visit_pat(p: &pat, (e, v): (E, vt)) { } } } - pat_struct(path, ref fields, _) => { + pat_struct(ref path, ref fields, _) => { visit_path(path, (copy e, v)); for fields.iter().advance |f| { (v.visit_pat)(f.pat, (copy e, v)); @@ -294,7 +294,7 @@ pub fn visit_pat(p: &pat, (e, v): (E, vt)) { pat_box(inner) | pat_uniq(inner) | pat_region(inner) => { (v.visit_pat)(inner, (e, v)) }, - pat_ident(_, path, ref inner) => { + pat_ident(_, ref path, ref inner) => { visit_path(path, (copy e, v)); for inner.iter().advance |subpat| { (v.visit_pat)(*subpat, (copy e, v)) @@ -458,7 +458,7 @@ pub fn visit_expr(ex: @expr, (e, v): (E, vt)) { (v.visit_expr)(element, (copy e, v)); (v.visit_expr)(count, (copy e, v)); } - expr_struct(p, ref flds, base) => { + expr_struct(ref p, ref flds, base) => { visit_path(p, (copy e, v)); for flds.iter().advance |f| { (v.visit_expr)(f.node.expr, (copy e, v)); @@ -534,7 +534,7 @@ pub fn visit_expr(ex: @expr, (e, v): (E, vt)) { (v.visit_expr)(a, (copy e, v)); (v.visit_expr)(b, (copy e, v)); } - expr_path(p) => visit_path(p, (copy e, v)), + expr_path(ref p) => visit_path(p, (copy e, v)), expr_self => (), expr_break(_) => (), expr_again(_) => (), From 62c83bb17be9a47799d702a9470aa7a84012c782 Mon Sep 17 00:00:00 2001 From: James Miller Date: Sat, 6 Jul 2013 00:33:52 +1200 Subject: [PATCH 75/93] De-manage Lifetime --- src/librustc/middle/region.rs | 18 +++++++------- src/librustc/middle/typeck/astconv.rs | 32 ++++++++++++------------- src/librustc/middle/typeck/check/mod.rs | 4 ++-- src/libsyntax/ast.rs | 10 ++++---- src/libsyntax/ext/build.rs | 8 +++---- src/libsyntax/ext/deriving/generic.rs | 2 +- src/libsyntax/ext/deriving/ty.rs | 9 ++++--- src/libsyntax/parse/parser.rs | 20 ++++++++-------- src/libsyntax/print/pprust.rs | 20 ++++++++-------- 9 files changed, 61 insertions(+), 62 deletions(-) diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 69cdbbb89771..a5b64ea42684 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -651,18 +651,18 @@ impl DetermineRpCtxt { // with &self type, &self is also bound. We detect those last two // cases via flags (anon_implies_rp and self_implies_rp) that are // true when the anon or self region implies RP. - pub fn region_is_relevant(&self, r: Option<@ast::Lifetime>) -> bool { + pub fn region_is_relevant(&self, r: &Option) -> bool { match r { - None => { + &None => { self.anon_implies_rp } - Some(ref l) if l.ident == special_idents::statik => { + &Some(ref l) if l.ident == special_idents::statik => { false } - Some(ref l) if l.ident == special_idents::self_ => { + &Some(ref l) if l.ident == special_idents::self_ => { true } - Some(_) => { + &Some(_) => { false } } @@ -747,7 +747,7 @@ fn determine_rp_in_ty(ty: @ast::Ty, // locations) let sess = cx.sess; match ty.node { - ast::ty_rptr(r, _) => { + ast::ty_rptr(ref r, _) => { debug!("referenced rptr type %s", pprust::ty_to_str(ty, sess.intr())); @@ -762,7 +762,7 @@ fn determine_rp_in_ty(ty: @ast::Ty, pprust::ty_to_str(ty, sess.intr())); match f.region { Some(_) => { - if cx.region_is_relevant(f.region) { + if cx.region_is_relevant(&f.region) { let rv = cx.add_variance(rv_contravariant); cx.add_rp(cx.item_id, rv) } @@ -790,7 +790,7 @@ fn determine_rp_in_ty(ty: @ast::Ty, Some(&ast::def_trait(did)) | Some(&ast::def_struct(did)) => { if did.crate == ast::local_crate { - if cx.region_is_relevant(path.rp) { + if cx.region_is_relevant(&path.rp) { cx.add_dep(did.node); } } else { @@ -800,7 +800,7 @@ fn determine_rp_in_ty(ty: @ast::Ty, Some(variance) => { debug!("reference to external, rp'd type %s", pprust::ty_to_str(ty, sess.intr())); - if cx.region_is_relevant(path.rp) { + if cx.region_is_relevant(&path.rp) { let rv = cx.add_variance(variance); cx.add_rp(cx.item_id, rv) } diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 1cab6607077d..b391180bbcdb 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -85,15 +85,15 @@ pub trait AstConv { pub fn get_region_reporting_err( tcx: ty::ctxt, span: span, - a_r: Option<@ast::Lifetime>, + a_r: &Option, res: Result) -> ty::Region { match res { result::Ok(r) => r, result::Err(ref e) => { let descr = match a_r { - None => ~"anonymous lifetime", - Some(a) => fmt!("lifetime %s", + &None => ~"anonymous lifetime", + &Some(ref a) => fmt!("lifetime %s", lifetime_to_str(a, tcx.sess.intr())) }; tcx.sess.span_err( @@ -109,19 +109,19 @@ pub fn ast_region_to_region( this: &AC, rscope: &RS, default_span: span, - opt_lifetime: Option<@ast::Lifetime>) -> ty::Region + opt_lifetime: &Option) -> ty::Region { let (span, res) = match opt_lifetime { - None => { + &None => { (default_span, rscope.anon_region(default_span)) } - Some(ref lifetime) if lifetime.ident == special_idents::statik => { + &Some(ref lifetime) if lifetime.ident == special_idents::statik => { (lifetime.span, Ok(ty::re_static)) } - Some(ref lifetime) if lifetime.ident == special_idents::self_ => { + &Some(ref lifetime) if lifetime.ident == special_idents::self_ => { (lifetime.span, rscope.self_region(lifetime.span)) } - Some(ref lifetime) => { + &Some(ref lifetime) => { (lifetime.span, rscope.named_region(lifetime.span, lifetime.ident)) } @@ -164,11 +164,11 @@ fn ast_path_substs( } (&Some(_), &None) => { let res = rscope.anon_region(path.span); - let r = get_region_reporting_err(this.tcx(), path.span, None, res); + let r = get_region_reporting_err(this.tcx(), path.span, &None, res); Some(r) } (&Some(_), &Some(_)) => { - Some(ast_region_to_region(this, rscope, path.span, path.rp)) + Some(ast_region_to_region(this, rscope, path.span, &path.rp)) } }; @@ -371,7 +371,7 @@ pub fn ast_ty_to_ty( ast::ty_ptr(ref mt) => { ty::mk_ptr(tcx, ast_mt_to_mt(this, rscope, mt)) } - ast::ty_rptr(region, ref mt) => { + ast::ty_rptr(ref region, ref mt) => { let r = ast_region_to_region(this, rscope, ast_ty.span, region); mk_pointer(this, rscope, mt, ty::vstore_slice(r), |tmt| ty::mk_rptr(tcx, r, tmt)) @@ -398,7 +398,7 @@ pub fn ast_ty_to_ty( f.purity, f.onceness, bounds, - f.region, + &f.region, &f.decl, None, &f.lifetimes, @@ -647,7 +647,7 @@ fn ty_of_method_or_bare_fn( ast::sty_value => { Some(self_info.untransformed_self_ty) } - ast::sty_region(lifetime, mutability) => { + ast::sty_region(ref lifetime, mutability) => { let region = ast_region_to_region(this, rscope, self_info.explicit_self.span, @@ -677,7 +677,7 @@ pub fn ty_of_closure( purity: ast::purity, onceness: ast::Onceness, bounds: ty::BuiltinBounds, - opt_lifetime: Option<@ast::Lifetime>, + opt_lifetime: &Option, decl: &ast::fn_decl, expected_sig: Option, lifetimes: &OptVec, @@ -695,10 +695,10 @@ pub fn ty_of_closure( // resolve the function bound region in the original region // scope `rscope`, not the scope of the function parameters let bound_region = match opt_lifetime { - Some(_) => { + &Some(_) => { ast_region_to_region(this, rscope, span, opt_lifetime) } - None => { + &None => { match sigil { ast::OwnedSigil | ast::ManagedSigil => { // @fn(), ~fn() default to static as the bound diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index f595b2dfc6a0..cd66c765a2d6 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -1738,7 +1738,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, purity, expected_onceness, expected_bounds, - None, + &None, decl, expected_sig, &opt_vec::Empty, @@ -3310,7 +3310,7 @@ pub fn instantiate_path(fcx: @mut FnCtxt, None } Some(_) => { // ...and the type is lifetime parameterized, ok. - Some(ast_region_to_region(fcx, fcx, span, pth.rp)) + Some(ast_region_to_region(fcx, fcx, span, &pth.rp)) } } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index d053c203b91a..9c3111a69183 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -109,7 +109,7 @@ pub struct Path { span: span, global: bool, idents: ~[ident], - rp: Option<@Lifetime>, + rp: Option, types: ~[@Ty], } @@ -296,7 +296,7 @@ pub enum vstore { vstore_fixed(Option), // [1,2,3,4] vstore_uniq, // ~[1,2,3,4] vstore_box, // @[1,2,3,4] - vstore_slice(Option<@Lifetime>) // &'foo? [1,2,3,4] + vstore_slice(Option) // &'foo? [1,2,3,4] } #[deriving(Eq, Encodable, Decodable,IterBytes)] @@ -701,7 +701,7 @@ impl ToStr for Onceness { #[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct TyClosure { sigil: Sigil, - region: Option<@Lifetime>, + region: Option, lifetimes: OptVec, purity: purity, onceness: Onceness, @@ -730,7 +730,7 @@ pub enum ty_ { ty_vec(mt), ty_fixed_length_vec(mt, @expr), ty_ptr(mt), - ty_rptr(Option<@Lifetime>, mt), + ty_rptr(Option, mt), ty_closure(@TyClosure), ty_bare_fn(@TyBareFn), ty_tup(~[@Ty]), @@ -803,7 +803,7 @@ pub enum ret_style { pub enum explicit_self_ { sty_static, // no self sty_value, // `self` - sty_region(Option<@Lifetime>, mutability), // `&'lt self` + sty_region(Option, mutability), // `&'lt self` sty_box(mutability), // `@self` sty_uniq // `~self` } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index c933caa16c4c..14ecc26a1c2b 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -38,7 +38,7 @@ pub trait AstBuilder { fn path_all(&self, sp: span, global: bool, idents: ~[ast::ident], - rp: Option<@ast::Lifetime>, + rp: Option, types: ~[@ast::Ty]) -> ast::Path; @@ -51,7 +51,7 @@ pub trait AstBuilder { fn ty_rptr(&self, span: span, ty: @ast::Ty, - lifetime: Option<@ast::Lifetime>, + lifetime: Option, mutbl: ast::mutability) -> @ast::Ty; fn ty_uniq(&self, span: span, ty: @ast::Ty) -> @ast::Ty; @@ -238,7 +238,7 @@ impl AstBuilder for @ExtCtxt { fn path_all(&self, sp: span, global: bool, idents: ~[ast::ident], - rp: Option<@ast::Lifetime>, + rp: Option, types: ~[@ast::Ty]) -> ast::Path { ast::Path { @@ -281,7 +281,7 @@ impl AstBuilder for @ExtCtxt { fn ty_rptr(&self, span: span, ty: @ast::Ty, - lifetime: Option<@ast::Lifetime>, + lifetime: Option, mutbl: ast::mutability) -> @ast::Ty { self.ty(span, diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index e397a4163045..8bd74b96afc1 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -351,7 +351,7 @@ impl<'self> TraitDef<'self> { let self_lifetime = if generics.lifetimes.is_empty() { None } else { - Some(@*generics.lifetimes.get(0)) + Some(*generics.lifetimes.get(0)) }; // Create the type of `self`. diff --git a/src/libsyntax/ext/deriving/ty.rs b/src/libsyntax/ext/deriving/ty.rs index 4dee2e2cdb89..2a60a20b8722 100644 --- a/src/libsyntax/ext/deriving/ty.rs +++ b/src/libsyntax/ext/deriving/ty.rs @@ -110,9 +110,9 @@ pub fn nil_ty() -> Ty<'static> { Tuple(~[]) } -fn mk_lifetime(cx: @ExtCtxt, span: span, lt: &Option<&str>) -> Option<@ast::Lifetime> { +fn mk_lifetime(cx: @ExtCtxt, span: span, lt: &Option<&str>) -> Option { match *lt { - Some(ref s) => Some(@cx.lifetime(span, cx.ident_of(*s))), + Some(ref s) => Some(cx.lifetime(span, cx.ident_of(*s))), None => None } } @@ -171,7 +171,7 @@ impl<'self> Ty<'self> { let lifetime = if self_generics.lifetimes.is_empty() { None } else { - Some(@*self_generics.lifetimes.get(0)) + Some(*self_generics.lifetimes.get(0)) }; cx.path_all(span, false, ~[self_ty], lifetime, @@ -251,8 +251,7 @@ pub fn get_explicit_self(cx: @ExtCtxt, span: span, self_ptr: &Option) Send => ast::sty_uniq, Managed(mutbl) => ast::sty_box(mutbl), Borrowed(ref lt, mutbl) => { - let lt = lt.map(|s| @cx.lifetime(span, - cx.ident_of(*s))); + let lt = lt.map(|s| cx.lifetime(span, cx.ident_of(*s))); ast::sty_region(lt, mutbl) } }); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 00386f611b14..1959649a8654 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -646,7 +646,7 @@ impl Parser { // parse a ty_closure type pub fn parse_ty_closure(&self, sigil: ast::Sigil, - region: Option<@ast::Lifetime>) + region: Option) -> ty_ { /* @@ -985,7 +985,7 @@ impl Parser { // @'foo fn() or @foo/fn() or @fn() are parsed directly as fn types: match *self.token { token::LIFETIME(*) => { - let lifetime = @self.parse_lifetime(); + let lifetime = self.parse_lifetime(); self.bump(); return self.parse_ty_closure(sigil, Some(lifetime)); } @@ -994,7 +994,7 @@ impl Parser { if self.look_ahead(1u) == token::BINOP(token::SLASH) && self.token_is_closure_keyword(&self.look_ahead(2u)) { - let lifetime = @self.parse_lifetime(); + let lifetime = self.parse_lifetime(); self.obsolete(*self.last_span, ObsoleteLifetimeNotation); return self.parse_ty_closure(sigil, Some(lifetime)); } else if self.token_is_closure_keyword(© *self.token) { @@ -1263,7 +1263,7 @@ impl Parser { token::IDENT(sid, _) => { let span = copy self.span; self.bump(); - Some(@ast::Lifetime { + Some(ast::Lifetime { id: self.get_id(), span: *span, ident: sid @@ -1288,7 +1288,7 @@ impl Parser { if v.len() == 0 { None } else if v.len() == 1 { - Some(@*v.get(0)) + Some(*v.get(0)) } else { self.fatal(fmt!("Expected at most one \ lifetime name (for now)")); @@ -1322,17 +1322,17 @@ impl Parser { } /// parses 0 or 1 lifetime - pub fn parse_opt_lifetime(&self) -> Option<@ast::Lifetime> { + pub fn parse_opt_lifetime(&self) -> Option { match *self.token { token::LIFETIME(*) => { - Some(@self.parse_lifetime()) + Some(self.parse_lifetime()) } // Also accept the (obsolete) syntax `foo/` token::IDENT(*) => { if self.look_ahead(1u) == token::BINOP(token::SLASH) { self.obsolete(*self.last_span, ObsoleteLifetimeNotation); - Some(@self.parse_lifetime()) + Some(self.parse_lifetime()) } else { None } @@ -3343,14 +3343,14 @@ impl Parser { } else if (this.token_is_lifetime(&this.look_ahead(1)) && token::is_keyword(keywords::Self, &this.look_ahead(2))) { this.bump(); - let lifetime = @this.parse_lifetime(); + let lifetime = this.parse_lifetime(); this.expect_self_ident(); sty_region(Some(lifetime), m_imm) } else if (this.token_is_lifetime(&this.look_ahead(1)) && this.token_is_mutability(&this.look_ahead(2)) && token::is_keyword(keywords::Self, &this.look_ahead(3))) { this.bump(); - let lifetime = @this.parse_lifetime(); + let lifetime = this.parse_lifetime(); let mutability = this.parse_mutability(); this.expect_self_ident(); sty_region(Some(lifetime), mutability) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 36e9ba4b08a2..d50eb8453d2f 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -366,9 +366,9 @@ pub fn print_foreign_mod(s: @ps, nmod: &ast::foreign_mod, for nmod.items.iter().advance |item| { print_foreign_item(s, *item); } } -pub fn print_opt_lifetime(s: @ps, lifetime: Option<@ast::Lifetime>) { +pub fn print_opt_lifetime(s: @ps, lifetime: &Option) { for lifetime.iter().advance |l| { - print_lifetime(s, *l); + print_lifetime(s, l); nbsp(s); } } @@ -392,7 +392,7 @@ pub fn print_type(s: @ps, ty: @ast::Ty) { word(s.s, "]"); } ast::ty_ptr(ref mt) => { word(s.s, "*"); print_mt(s, mt); } - ast::ty_rptr(lifetime, ref mt) => { + ast::ty_rptr(ref lifetime, ref mt) => { word(s.s, "&"); print_opt_lifetime(s, lifetime); print_mt(s, mt); @@ -408,14 +408,14 @@ pub fn print_type(s: @ps, ty: @ast::Ty) { ast::ty_bare_fn(f) => { let generics = ast::Generics {lifetimes: copy f.lifetimes, ty_params: opt_vec::Empty}; - print_ty_fn(s, Some(f.abis), None, None, + print_ty_fn(s, Some(f.abis), None, &None, f.purity, ast::Many, &f.decl, None, &None, Some(&generics), None); } ast::ty_closure(f) => { let generics = ast::Generics {lifetimes: copy f.lifetimes, ty_params: opt_vec::Empty}; - print_ty_fn(s, None, Some(f.sigil), f.region, + print_ty_fn(s, None, Some(f.sigil), &f.region, f.purity, f.onceness, &f.decl, None, &f.bounds, Some(&generics), None); } @@ -804,7 +804,7 @@ pub fn print_ty_method(s: @ps, m: &ast::ty_method) { hardbreak_if_not_bol(s); maybe_print_comment(s, m.span.lo); print_outer_attributes(s, m.attrs); - print_ty_fn(s, None, None, None, m.purity, ast::Many, + print_ty_fn(s, None, None, &None, m.purity, ast::Many, &m.decl, Some(m.ident), &None, Some(&m.generics), Some(/*bad*/ copy m.explicit_self.node)); word(s.s, ";"); @@ -1021,7 +1021,7 @@ pub fn print_vstore(s: @ps, t: ast::vstore) { ast::vstore_fixed(None) => word(s.s, "_"), ast::vstore_uniq => word(s.s, "~"), ast::vstore_box => word(s.s, "@"), - ast::vstore_slice(r) => { + ast::vstore_slice(ref r) => { word(s.s, "&"); print_opt_lifetime(s, r); } @@ -1505,7 +1505,7 @@ fn print_path_(s: @ps, path: &ast::Path, colons_before_params: bool, word(s.s, "<"); for path.rp.iter().advance |r| { - print_lifetime(s, *r); + print_lifetime(s, r); if !path.types.is_empty() { word_space(s, ","); } @@ -1653,7 +1653,7 @@ pub fn print_explicit_self(s: @ps, explicit_self: ast::explicit_self_) -> bool { ast::sty_static => { return false; } ast::sty_value => { word(s.s, "self"); } ast::sty_uniq => { word(s.s, "~self"); } - ast::sty_region(lt, m) => { + ast::sty_region(ref lt, m) => { word(s.s, "&"); print_opt_lifetime(s, lt); print_mutability(s, m); @@ -1912,7 +1912,7 @@ pub fn print_arg(s: @ps, input: ast::arg) { pub fn print_ty_fn(s: @ps, opt_abis: Option, opt_sigil: Option, - opt_region: Option<@ast::Lifetime>, + opt_region: &Option, purity: ast::purity, onceness: ast::Onceness, decl: &ast::fn_decl, From 97c5a44d3e805652a54a5693bbf2ab6d44db993b Mon Sep 17 00:00:00 2001 From: James Miller Date: Sat, 6 Jul 2013 12:47:42 +1200 Subject: [PATCH 76/93] De-share trait_ref Also, makes the pretty-printer use & instead of @ as much as possible, which will help with later changes, though in the interim has produced some... interesting constructs. --- src/librustc/front/config.rs | 4 +- src/librustc/metadata/decoder.rs | 2 +- src/librustc/metadata/encoder.rs | 2 +- src/librustc/middle/kind.rs | 2 +- src/librustc/middle/reachable.rs | 2 +- src/librustc/middle/resolve.rs | 10 +- src/librustc/middle/ty.rs | 6 +- src/librustc/middle/typeck/astconv.rs | 2 +- src/librustc/middle/typeck/coherence.rs | 18 +-- src/librustc/middle/typeck/collect.rs | 14 +-- src/libsyntax/ast.rs | 6 +- src/libsyntax/ast_util.rs | 2 +- src/libsyntax/ext/build.rs | 6 +- src/libsyntax/ext/log_syntax.rs | 2 +- src/libsyntax/ext/tt/macro_rules.rs | 2 +- src/libsyntax/fold.rs | 12 +- src/libsyntax/parse/parser.rs | 8 +- src/libsyntax/print/pprust.rs | 151 ++++++++++++------------ src/libsyntax/visit.rs | 4 +- 19 files changed, 128 insertions(+), 127 deletions(-) diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs index 12c7a0843ce4..0f71eeff5a2f 100644 --- a/src/librustc/front/config.rs +++ b/src/librustc/front/config.rs @@ -98,10 +98,10 @@ fn fold_foreign_mod( fn fold_item_underscore(cx: @Context, item: &ast::item_, fld: @fold::ast_fold) -> ast::item_ { let item = match *item { - ast::item_impl(ref a, b, c, ref methods) => { + ast::item_impl(ref a, ref b, c, ref methods) => { let methods = methods.iter().filter(|m| method_in_cfg(cx, **m)) .transform(|x| *x).collect(); - ast::item_impl(/*bad*/ copy *a, b, c, methods) + ast::item_impl(/*bad*/ copy *a, /*bad*/ copy *b, c, methods) } ast::item_trait(ref a, ref b, ref methods) => { let methods = methods.iter().filter(|m| trait_method_in_cfg(cx, *m) ) diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 2c7a991f6146..1e508d081318 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -1141,7 +1141,7 @@ fn list_crate_attributes(intr: @ident_interner, md: ebml::Doc, hash: &str, let r = get_attributes(md); for r.iter().advance |attr| { - out.write_str(fmt!("%s\n", pprust::attribute_to_str(*attr, intr))); + out.write_str(fmt!("%s\n", pprust::attribute_to_str(attr, intr))); } out.write_str("\n\n"); diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 91dba63a182e..9b4c39b3fc78 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1003,7 +1003,7 @@ fn encode_info_for_item(ecx: &EncodeContext, index); } } - item_impl(ref generics, opt_trait, ty, ref methods) => { + item_impl(ref generics, ref opt_trait, ty, ref methods) => { add_to_index(); ebml_w.start_tag(tag_items_data_item); encode_def_id(ebml_w, local_def(item.id)); diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index cba094d619e0..0c493fe9e81c 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -117,7 +117,7 @@ fn check_item(item: @item, (cx, visitor): (Context, visit::vt)) { // If this is a destructor, check kinds. if !attrs_contains_name(item.attrs, "unsafe_destructor") { match item.node { - item_impl(_, Some(trait_ref), self_type, _) => { + item_impl(_, Some(ref trait_ref), self_type, _) => { match cx.tcx.def_map.find(&trait_ref.ref_id) { None => cx.tcx.sess.bug("trait ref not in def map!"), Some(&trait_def) => { diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 97bad93dc358..70833813cc08 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -141,7 +141,7 @@ impl ReachableContext { } } } - item_impl(ref generics, trait_ref, _, ref methods) => { + item_impl(ref generics, ref trait_ref, _, ref methods) => { // XXX(pcwalton): We conservatively assume any methods // on a trait implementation are reachable, when this // is not the case. We could be more precise by only diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 8f73c8fc1730..3b90d72deb12 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -3533,7 +3533,7 @@ impl Resolver { } item_impl(ref generics, - implemented_traits, + ref implemented_traits, self_type, ref methods) => { self.resolve_implementation(item.id, @@ -3811,7 +3811,7 @@ impl Resolver { type_parameter_bound: &TyParamBound, visitor: ResolveVisitor) { match *type_parameter_bound { - TraitTyParamBound(tref) => { + TraitTyParamBound(ref tref) => { self.resolve_trait_reference(tref, visitor, TraitBoundingTypeParameter) } RegionTyParamBound => {} @@ -3913,7 +3913,7 @@ impl Resolver { pub fn resolve_implementation(@mut self, id: node_id, generics: &Generics, - opt_trait_reference: Option<@trait_ref>, + opt_trait_reference: &Option, self_type: @Ty, methods: &[@method], visitor: ResolveVisitor) { @@ -3929,7 +3929,7 @@ impl Resolver { // Resolve the trait reference, if necessary. let original_trait_refs; match opt_trait_reference { - Some(trait_reference) => { + &Some(ref trait_reference) => { self.resolve_trait_reference(trait_reference, visitor, TraitImplementation); // Record the current set of trait references. @@ -3944,7 +3944,7 @@ impl Resolver { &mut self.current_trait_refs, Some(new_trait_refs))); } - None => { + &None => { original_trait_refs = None; } } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index feac8be8efd8..129208a9aa37 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3624,12 +3624,12 @@ pub fn impl_trait_ref(cx: ctxt, id: ast::def_id) -> Option<@TraitRef> { debug!("(impl_trait_ref) searching for trait impl %?", id); match cx.items.find(&id.node) { Some(&ast_map::node_item(@ast::item { - node: ast::item_impl(_, opt_trait, _, _), + node: ast::item_impl(_, ref opt_trait, _, _), _}, _)) => { match opt_trait { - Some(t) => Some(ty::node_id_to_trait_ref(cx, t.ref_id)), - None => None + &Some(ref t) => Some(ty::node_id_to_trait_ref(cx, t.ref_id)), + &None => None } } _ => None diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index b391180bbcdb..e224654f2d35 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -764,7 +764,7 @@ fn conv_builtin_bounds(tcx: ty::ctxt, ast_bounds: &Option { + ast::TraitTyParamBound(ref b) => { match lookup_def_tcx(tcx, b.path.span, b.ref_id) { ast::def_trait(trait_did) => { if try_add_builtin_trait(tcx, diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index 24ac63ac7b07..aef0e4b200b9 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -207,9 +207,11 @@ impl CoherenceChecker { // self.crate_context.tcx.sess.str_of(item.ident)); match item.node { - item_impl(_, opt_trait, _, _) => { - self.check_implementation(item, - opt_trait.iter().transform(|&x| x).collect()); + item_impl(_, ref opt_trait, _, _) => { + let opt_trait : ~[trait_ref] = opt_trait.iter() + .transform(|&x| x) + .collect(); + self.check_implementation(item, opt_trait); } _ => { // Nothing to do. @@ -238,7 +240,7 @@ impl CoherenceChecker { pub fn check_implementation(&self, item: @item, - associated_traits: ~[@trait_ref]) { + associated_traits: &[trait_ref]) { let tcx = self.crate_context.tcx; let self_type = ty::lookup_item_type(tcx, local_def(item.id)); @@ -646,7 +648,7 @@ impl CoherenceChecker { a trait or new type instead"); } } - item_impl(_, Some(trait_ref), _, _) => { + item_impl(_, Some(ref trait_ref), _, _) => { // `for_ty` is `Type` in `impl Trait for Type` let for_ty = ty::node_id_to_type(self.crate_context.tcx, @@ -678,7 +680,7 @@ impl CoherenceChecker { }))); } - pub fn trait_ref_to_trait_def_id(&self, trait_ref: @trait_ref) -> def_id { + pub fn trait_ref_to_trait_def_id(&self, trait_ref: &trait_ref) -> def_id { let def_map = self.crate_context.tcx.def_map; let trait_def = def_map.get_copy(&trait_ref.ref_id); let trait_id = def_id_of_def(trait_def); @@ -805,7 +807,7 @@ impl CoherenceChecker { // Check that we have implementations of every trait method for trait_refs.iter().advance |trait_ref| { let trait_did = - self.trait_ref_to_trait_def_id(*trait_ref); + self.trait_ref_to_trait_def_id(trait_ref); self.please_check_that_trait_methods_are_implemented( &mut methods, trait_did, @@ -817,7 +819,7 @@ impl CoherenceChecker { // if a method of that name is not inherent to the // impl, use the provided definition in the trait. for trait_refs.iter().advance |trait_ref| { - let trait_did = self.trait_ref_to_trait_def_id(*trait_ref); + let trait_did = self.trait_ref_to_trait_def_id(trait_ref); self.add_provided_methods_to_impl( &mut methods, &trait_did, diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index b642eff12a8d..60f97a0ae0a0 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -378,7 +378,7 @@ pub fn ensure_supertraits(ccx: &CrateCtxt, id: ast::node_id, sp: codemap::span, rp: Option, - ast_trait_refs: &[@ast::trait_ref], + ast_trait_refs: &[ast::trait_ref], generics: &ast::Generics) { let tcx = ccx.tcx; @@ -386,7 +386,7 @@ pub fn ensure_supertraits(ccx: &CrateCtxt, let self_ty = ty::mk_self(ccx.tcx, local_def(id)); let mut ty_trait_refs: ~[@ty::TraitRef] = ~[]; - for ast_trait_refs.iter().advance |&ast_trait_ref| { + for ast_trait_refs.iter().advance |ast_trait_ref| { let trait_ref = instantiate_trait_ref(ccx, ast_trait_ref, rp, generics, self_ty); @@ -441,7 +441,7 @@ pub fn compare_impl_method(tcx: ty::ctxt, fmt!("method `%s` has a `%s` declaration in the impl, \ but not in the trait", tcx.sess.str_of(trait_m.ident), - explicit_self_to_str(impl_m.explicit_self, tcx.sess.intr()))); + explicit_self_to_str(&impl_m.explicit_self, tcx.sess.intr()))); return; } (_, &ast::sty_static) => { @@ -450,7 +450,7 @@ pub fn compare_impl_method(tcx: ty::ctxt, fmt!("method `%s` has a `%s` declaration in the trait, \ but not in the impl", tcx.sess.str_of(trait_m.ident), - explicit_self_to_str(trait_m.explicit_self, tcx.sess.intr()))); + explicit_self_to_str(&trait_m.explicit_self, tcx.sess.intr()))); return; } _ => { @@ -813,7 +813,7 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::item) { generics, rp); } - ast::item_impl(ref generics, opt_trait_ref, selfty, ref ms) => { + ast::item_impl(ref generics, ref opt_trait_ref, selfty, ref ms) => { let i_ty_generics = ty_generics(ccx, rp, generics, 0); let region_parameterization = RegionParameterization::from_variance_and_generics(rp, generics); @@ -839,7 +839,7 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::item) { &i_ty_generics, generics, parent_visibility); for opt_trait_ref.iter().advance |t| { - check_methods_against_trait(ccx, generics, rp, selfty, *t, cms); + check_methods_against_trait(ccx, generics, rp, selfty, t, cms); } } ast::item_trait(ref generics, ref supertraits, ref trait_methods) => { @@ -1184,7 +1184,7 @@ pub fn ty_generics(ccx: &CrateCtxt, }; for ast_bounds.iter().advance |ast_bound| { match *ast_bound { - TraitTyParamBound(b) => { + TraitTyParamBound(ref b) => { let ty = ty::mk_param(ccx.tcx, param_ty.idx, param_ty.def_id); let trait_ref = instantiate_trait_ref(ccx, b, rp, generics, ty); if !astconv::try_add_builtin_trait( diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 9c3111a69183..a222f03820fc 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -132,7 +132,7 @@ pub static crate_node_id: node_id = 0; // the "special" built-in traits (see middle::lang_items) and // detects Copy, Send, Send, and Freeze. pub enum TyParamBound { - TraitTyParamBound(@trait_ref), + TraitTyParamBound(trait_ref), RegionTyParamBound } @@ -1002,9 +1002,9 @@ pub enum item_ { item_ty(@Ty, Generics), item_enum(enum_def, Generics), item_struct(@struct_def, Generics), - item_trait(Generics, ~[@trait_ref], ~[trait_method]), + item_trait(Generics, ~[trait_ref], ~[trait_method]), item_impl(Generics, - Option<@trait_ref>, // (optional) trait this impl implements + Option, // (optional) trait this impl implements @Ty, // self ~[@method]), // a macro invocation (which includes macro definition) diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 35f9782f694f..565f181ab859 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -580,7 +580,7 @@ pub fn view_path_id(p: &view_path) -> node_id { /// Returns true if the given struct def is tuple-like; i.e. that its fields /// are unnamed. -pub fn struct_def_is_tuple_like(struct_def: @ast::struct_def) -> bool { +pub fn struct_def_is_tuple_like(struct_def: &ast::struct_def) -> bool { struct_def.ctor_id.is_some() } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 14ecc26a1c2b..68b011e4fd7a 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -68,7 +68,7 @@ pub trait AstBuilder { fn typaram(&self, id: ast::ident, bounds: @OptVec) -> ast::TyParam; - fn trait_ref(&self, path: ast::Path) -> @ast::trait_ref; + fn trait_ref(&self, path: ast::Path) -> ast::trait_ref; fn typarambound(&self, path: ast::Path) -> ast::TyParamBound; fn lifetime(&self, span: span, ident: ast::ident) -> ast::Lifetime; @@ -358,8 +358,8 @@ impl AstBuilder for @ExtCtxt { } } - fn trait_ref(&self, path: ast::Path) -> @ast::trait_ref { - @ast::trait_ref { + fn trait_ref(&self, path: ast::Path) -> ast::trait_ref { + ast::trait_ref { path: path, ref_id: self.next_id() } diff --git a/src/libsyntax/ext/log_syntax.rs b/src/libsyntax/ext/log_syntax.rs index 5b789cbc26c1..9e6776363a82 100644 --- a/src/libsyntax/ext/log_syntax.rs +++ b/src/libsyntax/ext/log_syntax.rs @@ -26,7 +26,7 @@ pub fn expand_syntax_ext(cx: @ExtCtxt, cx.print_backtrace(); io::stdout().write_line( print::pprust::tt_to_str( - ast::tt_delim(vec::to_owned(tt)), + &ast::tt_delim(vec::to_owned(tt)), get_ident_interner())); //trivial expression diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 80dd0c7247b4..6de504c66fd8 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -82,7 +82,7 @@ pub fn add_new_extension(cx: @ExtCtxt, io::println(fmt!("%s! { %s }", cx.str_of(name), print::pprust::tt_to_str( - ast::tt_delim(vec::to_owned(arg)), + &ast::tt_delim(vec::to_owned(arg)), get_ident_interner()))); } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index e9710c9e114d..85eb499069bd 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -162,7 +162,7 @@ pub fn fold_fn_decl(decl: &ast::fn_decl, fld: @ast_fold) -> ast::fn_decl { fn fold_ty_param_bound(tpb: &TyParamBound, fld: @ast_fold) -> TyParamBound { match *tpb { - TraitTyParamBound(ty) => TraitTyParamBound(fold_trait_ref(ty, fld)), + TraitTyParamBound(ref ty) => TraitTyParamBound(fold_trait_ref(ty, fld)), RegionTyParamBound => RegionTyParamBound } } @@ -296,10 +296,10 @@ pub fn noop_fold_item_underscore(i: &item_, fld: @ast_fold) -> item_ { let struct_def = fold_struct_def(*struct_def, fld); item_struct(struct_def, /* FIXME (#2543) */ copy *generics) } - item_impl(ref generics, ifce, ty, ref methods) => { + item_impl(ref generics, ref ifce, ty, ref methods) => { item_impl( fold_generics(generics, fld), - ifce.map(|p| fold_trait_ref(*p, fld)), + ifce.map(|p| fold_trait_ref(p, fld)), fld.fold_ty(ty), methods.map(|x| fld.fold_method(*x)) ) @@ -313,7 +313,7 @@ pub fn noop_fold_item_underscore(i: &item_, fld: @ast_fold) -> item_ { }; item_trait( fold_generics(generics, fld), - traits.map(|p| fold_trait_ref(*p, fld)), + traits.map(|p| fold_trait_ref(p, fld)), methods ) } @@ -335,8 +335,8 @@ fn fold_struct_def(struct_def: @ast::struct_def, fld: @ast_fold) } } -fn fold_trait_ref(p: @trait_ref, fld: @ast_fold) -> @trait_ref { - @ast::trait_ref { +fn fold_trait_ref(p: &trait_ref, fld: @ast_fold) -> trait_ref { + ast::trait_ref { path: fld.fold_path(&p.path), ref_id: fld.new_id(p.ref_id), } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 1959649a8654..8f1bffdaa789 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3566,7 +3566,7 @@ impl Parser { // New-style trait. Reinterpret the type as a trait. let opt_trait_ref = match ty.node { ty_path(ref path, @None, node_id) => { - Some(@trait_ref { + Some(trait_ref { path: /* bad */ copy *path, ref_id: node_id }) @@ -3608,15 +3608,15 @@ impl Parser { } // parse a::B<~str,int> - fn parse_trait_ref(&self) -> @trait_ref { - @ast::trait_ref { + fn parse_trait_ref(&self) -> trait_ref { + ast::trait_ref { path: self.parse_path_with_tps(false), ref_id: self.get_id(), } } // parse B + C<~str,int> + D - fn parse_trait_ref_list(&self, ket: &token::Token) -> ~[@trait_ref] { + fn parse_trait_ref_list(&self, ket: &token::Token) -> ~[trait_ref] { self.parse_seq_to_before_end( ket, seq_sep_trailing_disallowed(token::BINOP(token::PLUS)), diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index d50eb8453d2f..d90055caffb9 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -34,9 +34,9 @@ use std::uint; // The @ps is stored here to prevent recursive type. pub enum ann_node<'self> { node_block(@ps, &'self ast::blk), - node_item(@ps, @ast::item), - node_expr(@ps, @ast::expr), - node_pat(@ps, @ast::pat), + node_item(@ps, &'self ast::item), + node_expr(@ps, &'self ast::expr), + node_pat(@ps, &'self ast::pat), } pub struct pp_ann { pre: @fn(ann_node), @@ -106,7 +106,7 @@ pub static default_columns: uint = 78u; pub fn print_crate(cm: @CodeMap, intr: @ident_interner, span_diagnostic: @diagnostic::span_handler, - crate: @ast::crate, + crate: &ast::crate, filename: @str, in: @io::Reader, out: @io::Writer, @@ -136,21 +136,21 @@ pub fn print_crate(cm: @CodeMap, print_crate_(s, crate); } -pub fn print_crate_(s: @ps, crate: @ast::crate) { +pub fn print_crate_(s: @ps, crate: &ast::crate) { print_mod(s, &crate.node.module, crate.node.attrs); print_remaining_comments(s); eof(s.s); } -pub fn ty_to_str(ty: @ast::Ty, intr: @ident_interner) -> ~str { +pub fn ty_to_str(ty: &ast::Ty, intr: @ident_interner) -> ~str { to_str(ty, print_type, intr) } -pub fn pat_to_str(pat: @ast::pat, intr: @ident_interner) -> ~str { +pub fn pat_to_str(pat: &ast::pat, intr: @ident_interner) -> ~str { to_str(pat, print_irrefutable_pat, intr) } -pub fn expr_to_str(e: @ast::expr, intr: @ident_interner) -> ~str { +pub fn expr_to_str(e: &ast::expr, intr: @ident_interner) -> ~str { to_str(e, print_expr, intr) } @@ -158,19 +158,19 @@ pub fn lifetime_to_str(e: &ast::Lifetime, intr: @ident_interner) -> ~str { to_str(e, print_lifetime, intr) } -pub fn tt_to_str(tt: ast::token_tree, intr: @ident_interner) -> ~str { - to_str(&tt, print_tt, intr) +pub fn tt_to_str(tt: &ast::token_tree, intr: @ident_interner) -> ~str { + to_str(tt, print_tt, intr) } pub fn tts_to_str(tts: &[ast::token_tree], intr: @ident_interner) -> ~str { - to_str(tts, print_tts, intr) + to_str(&tts, print_tts, intr) } pub fn stmt_to_str(s: &ast::stmt, intr: @ident_interner) -> ~str { to_str(s, print_stmt, intr) } -pub fn item_to_str(i: @ast::item, intr: @ident_interner) -> ~str { +pub fn item_to_str(i: &ast::item, intr: @ident_interner) -> ~str { to_str(i, print_item, intr) } @@ -208,11 +208,11 @@ pub fn block_to_str(blk: &ast::blk, intr: @ident_interner) -> ~str { } } -pub fn meta_item_to_str(mi: @ast::meta_item, intr: @ident_interner) -> ~str { +pub fn meta_item_to_str(mi: &ast::meta_item, intr: @ident_interner) -> ~str { to_str(mi, print_meta_item, intr) } -pub fn attribute_to_str(attr: ast::attribute, intr: @ident_interner) -> ~str { +pub fn attribute_to_str(attr: &ast::attribute, intr: @ident_interner) -> ~str { to_str(attr, print_attribute, intr) } @@ -314,30 +314,30 @@ pub fn synth_comment(s: @ps, text: ~str) { word(s.s, "*/"); } -pub fn commasep(s: @ps, b: breaks, elts: &[IN], op: &fn(@ps, IN)) { +pub fn commasep(s: @ps, b: breaks, elts: &[T], op: &fn(@ps, &T)) { box(s, 0u, b); let mut first = true; for elts.iter().advance |elt| { if first { first = false; } else { word_space(s, ","); } - op(s, copy *elt); + op(s, elt); } end(s); } -pub fn commasep_cmnt(s: @ps, b: breaks, elts: &[IN], op: &fn(@ps, IN), - get_span: &fn(IN) -> codemap::span) { +pub fn commasep_cmnt(s: @ps, b: breaks, elts: &[T], op: &fn(@ps, &T), + get_span: &fn(&T) -> codemap::span) { box(s, 0u, b); let len = elts.len(); let mut i = 0u; for elts.iter().advance |elt| { - maybe_print_comment(s, get_span(copy *elt).hi); - op(s, copy *elt); + maybe_print_comment(s, get_span(elt).hi); + op(s, elt); i += 1u; if i < len { word(s.s, ","); - maybe_print_trailing_comment(s, get_span(copy *elt), - Some(get_span(copy elts[i]).hi)); + maybe_print_trailing_comment(s, get_span(elt), + Some(get_span(&elts[i]).hi)); space_if_not_bol(s); } } @@ -345,8 +345,7 @@ pub fn commasep_cmnt(s: @ps, b: breaks, elts: &[IN], op: &fn(@ps, IN), } pub fn commasep_exprs(s: @ps, b: breaks, exprs: &[@ast::expr]) { - fn expr_span(expr: @ast::expr) -> codemap::span { return expr.span; } - commasep_cmnt(s, b, exprs, print_expr, expr_span); + commasep_cmnt(s, b, exprs, |p, &e| print_expr(p, e), |e| e.span); } pub fn print_mod(s: @ps, _mod: &ast::_mod, attrs: &[ast::attribute]) { @@ -373,7 +372,7 @@ pub fn print_opt_lifetime(s: @ps, lifetime: &Option) { } } -pub fn print_type(s: @ps, ty: @ast::Ty) { +pub fn print_type(s: @ps, ty: &ast::Ty) { maybe_print_comment(s, ty.span.lo); ibox(s, 0u); match ty.node { @@ -399,7 +398,7 @@ pub fn print_type(s: @ps, ty: @ast::Ty) { } ast::ty_tup(ref elts) => { popen(s); - commasep(s, inconsistent, *elts, print_type); + commasep(s, inconsistent, *elts, |p, &t| print_type(p, t)); if elts.len() == 1 { word(s.s, ","); } @@ -443,7 +442,7 @@ pub fn print_type(s: @ps, ty: @ast::Ty) { end(s); } -pub fn print_foreign_item(s: @ps, item: @ast::foreign_item) { +pub fn print_foreign_item(s: @ps, item: &ast::foreign_item) { hardbreak_if_not_bol(s); maybe_print_comment(s, item.span.lo); print_outer_attributes(s, item.attrs); @@ -470,7 +469,7 @@ pub fn print_foreign_item(s: @ps, item: @ast::foreign_item) { } } -pub fn print_item(s: @ps, item: @ast::item) { +pub fn print_item(s: @ps, item: &ast::item) { hardbreak_if_not_bol(s); maybe_print_comment(s, item.span.lo); print_outer_attributes(s, item.attrs); @@ -560,7 +559,7 @@ pub fn print_item(s: @ps, item: @ast::item) { print_struct(s, struct_def, generics, item.ident, item.span); } - ast::item_impl(ref generics, opt_trait, ty, ref methods) => { + ast::item_impl(ref generics, ref opt_trait, ty, ref methods) => { head(s, visibility_qualified(item.vis, "impl")); if generics.is_parameterized() { print_generics(s, generics); @@ -568,12 +567,12 @@ pub fn print_item(s: @ps, item: @ast::item) { } match opt_trait { - Some(t) => { + &Some(ref t) => { print_trait_ref(s, t); space(s.s); word_space(s, "for"); } - None => () + &None => () }; print_type(s, ty); @@ -618,7 +617,7 @@ pub fn print_item(s: @ps, item: @ast::item) { print_ident(s, item.ident); cbox(s, indent_unit); popen(s); - print_tts(s, *tts); + print_tts(s, &(tts.as_slice())); pclose(s); end(s); } @@ -681,7 +680,7 @@ pub fn print_visibility(s: @ps, vis: ast::visibility) { } pub fn print_struct(s: @ps, - struct_def: @ast::struct_def, + struct_def: &ast::struct_def, generics: &ast::Generics, ident: ast::ident, span: codemap::span) { @@ -738,7 +737,7 @@ pub fn print_struct(s: @ps, /// expression arguments as expressions). It can be done! I think. pub fn print_tt(s: @ps, tt: &ast::token_tree) { match *tt { - ast::tt_delim(ref tts) => print_tts(s, *tts), + ast::tt_delim(ref tts) => print_tts(s, &(tts.as_slice())), ast::tt_tok(_, ref tk) => { word(s.s, parse::token::to_str(s.intr, tk)); } @@ -759,7 +758,7 @@ pub fn print_tt(s: @ps, tt: &ast::token_tree) { } } -pub fn print_tts(s: @ps, tts: &[ast::token_tree]) { +pub fn print_tts(s: @ps, tts: & &[ast::token_tree]) { ibox(s, 0); for tts.iter().enumerate().advance |(i, tt)| { if i != 0 { @@ -777,7 +776,7 @@ pub fn print_variant(s: @ps, v: &ast::variant) { print_ident(s, v.node.name); if !args.is_empty() { popen(s); - fn print_variant_arg(s: @ps, arg: ast::variant_arg) { + fn print_variant_arg(s: @ps, arg: &ast::variant_arg) { print_type(s, arg.ty); } commasep(s, consistent, *args, print_variant_arg); @@ -817,7 +816,7 @@ pub fn print_trait_method(s: @ps, m: &ast::trait_method) { } } -pub fn print_method(s: @ps, meth: @ast::method) { +pub fn print_method(s: @ps, meth: &ast::method) { hardbreak_if_not_bol(s); maybe_print_comment(s, meth.span.lo); print_outer_attributes(s, meth.attrs); @@ -832,7 +831,7 @@ pub fn print_outer_attributes(s: @ps, attrs: &[ast::attribute]) { let mut count = 0; for attrs.iter().advance |attr| { match attr.node.style { - ast::attr_outer => { print_attribute(s, *attr); count += 1; } + ast::attr_outer => { print_attribute(s, attr); count += 1; } _ => {/* fallthrough */ } } } @@ -844,7 +843,7 @@ pub fn print_inner_attributes(s: @ps, attrs: &[ast::attribute]) { for attrs.iter().advance |attr| { match attr.node.style { ast::attr_inner => { - print_attribute(s, *attr); + print_attribute(s, attr); if !attr.node.is_sugared_doc { word(s.s, ";"); } @@ -856,11 +855,11 @@ pub fn print_inner_attributes(s: @ps, attrs: &[ast::attribute]) { if count > 0 { hardbreak_if_not_bol(s); } } -pub fn print_attribute(s: @ps, attr: ast::attribute) { +pub fn print_attribute(s: @ps, attr: &ast::attribute) { hardbreak_if_not_bol(s); maybe_print_comment(s, attr.span.lo); if attr.node.is_sugared_doc { - let meta = attr::attr_meta(attr); + let meta = attr::attr_meta(*attr); let comment = attr::get_meta_item_value_str(meta).get(); word(s.s, comment); } else { @@ -963,7 +962,7 @@ pub fn print_possibly_embedded_block_(s: @ps, (s.ann.post)(ann_node); } -pub fn print_if(s: @ps, test: @ast::expr, blk: &ast::blk, +pub fn print_if(s: @ps, test: &ast::expr, blk: &ast::blk, elseopt: Option<@ast::expr>, chk: bool) { head(s, "if"); if chk { word_nbsp(s, "check"); } @@ -1009,7 +1008,7 @@ pub fn print_mac(s: @ps, m: &ast::mac) { print_path(s, pth, false); word(s.s, "!"); popen(s); - print_tts(s, *tts); + print_tts(s, &tts.as_slice()); pclose(s); } } @@ -1088,15 +1087,15 @@ pub fn print_call_post(s: @ps, } } -pub fn print_expr(s: @ps, expr: @ast::expr) { - fn print_field(s: @ps, field: ast::field) { +pub fn print_expr(s: @ps, expr: &ast::expr) { + fn print_field(s: @ps, field: &ast::field) { ibox(s, indent_unit); print_ident(s, field.node.ident); word_space(s, ":"); print_expr(s, field.node.expr); end(s); } - fn get_span(field: ast::field) -> codemap::span { return field.span; } + fn get_span(field: &ast::field) -> codemap::span { return field.span; } maybe_print_comment(s, expr.span.lo); ibox(s, indent_unit); @@ -1173,7 +1172,7 @@ pub fn print_expr(s: @ps, expr: @ast::expr) { print_ident(s, ident); if tys.len() > 0u { word(s.s, "::<"); - commasep(s, inconsistent, *tys, print_type); + commasep(s, inconsistent, *tys, |p, &e| print_type(p, e)); word(s.s, ">"); } print_call_post(s, sugar, &blk, &mut base_args); @@ -1349,7 +1348,7 @@ pub fn print_expr(s: @ps, expr: @ast::expr) { print_ident(s, id); if tys.len() > 0u { word(s.s, "::<"); - commasep(s, inconsistent, *tys, print_type); + commasep(s, inconsistent, *tys, |p, &e| print_type(p, e)); word(s.s, ">"); } } @@ -1434,7 +1433,7 @@ pub fn print_expr(s: @ps, expr: @ast::expr) { end(s); } -pub fn print_local_decl(s: @ps, loc: @ast::local) { +pub fn print_local_decl(s: @ps, loc: &ast::local) { print_irrefutable_pat(s, loc.node.pat); match loc.node.ty.node { ast::ty_infer => (), @@ -1442,7 +1441,7 @@ pub fn print_local_decl(s: @ps, loc: @ast::local) { } } -pub fn print_decl(s: @ps, decl: @ast::decl) { +pub fn print_decl(s: @ps, decl: &ast::decl) { maybe_print_comment(s, decl.span.lo); match decl.node { ast::decl_local(ref loc) => { @@ -1454,7 +1453,7 @@ pub fn print_decl(s: @ps, decl: @ast::decl) { word_nbsp(s, "mut"); } - fn print_local(s: @ps, loc: @ast::local) { + fn print_local(s: @ps, loc: &ast::local) { ibox(s, indent_unit); print_local_decl(s, loc); end(s); @@ -1479,7 +1478,7 @@ pub fn print_ident(s: @ps, ident: ast::ident) { word(s.s, ident_to_str(&ident)); } -pub fn print_for_decl(s: @ps, loc: @ast::local, coll: @ast::expr) { +pub fn print_for_decl(s: @ps, loc: &ast::local, coll: &ast::expr) { print_local_decl(s, loc); space(s.s); word_space(s, "in"); @@ -1511,7 +1510,7 @@ fn print_path_(s: @ps, path: &ast::Path, colons_before_params: bool, } } - commasep(s, inconsistent, path.types, print_type); + commasep(s, inconsistent, path.types, |p, &e| print_type(p, e)); word(s.s, ">"); } @@ -1527,15 +1526,15 @@ pub fn print_bounded_path(s: @ps, path: &ast::Path, print_path_(s, path, false, bounds) } -pub fn print_irrefutable_pat(s: @ps, pat: @ast::pat) { +pub fn print_irrefutable_pat(s: @ps, pat: &ast::pat) { print_pat(s, pat, false) } -pub fn print_refutable_pat(s: @ps, pat: @ast::pat) { +pub fn print_refutable_pat(s: @ps, pat: &ast::pat) { print_pat(s, pat, true) } -pub fn print_pat(s: @ps, pat: @ast::pat, refutable: bool) { +pub fn print_pat(s: @ps, pat: &ast::pat, refutable: bool) { maybe_print_comment(s, pat.span.lo); let ann_node = node_pat(s, pat); (s.ann.pre)(ann_node); @@ -1570,7 +1569,7 @@ pub fn print_pat(s: @ps, pat: @ast::pat, refutable: bool) { if !args.is_empty() { popen(s); commasep(s, inconsistent, *args, - |s, p| print_pat(s, p, refutable)); + |s, &p| print_pat(s, p, refutable)); pclose(s); } else { } } @@ -1579,14 +1578,14 @@ pub fn print_pat(s: @ps, pat: @ast::pat, refutable: bool) { ast::pat_struct(ref path, ref fields, etc) => { print_path(s, path, true); word(s.s, "{"); - fn print_field(s: @ps, f: ast::field_pat, refutable: bool) { + fn print_field(s: @ps, f: &ast::field_pat, refutable: bool) { cbox(s, indent_unit); print_ident(s, f.ident); word_space(s, ":"); print_pat(s, f.pat, refutable); end(s); } - fn get_span(f: ast::field_pat) -> codemap::span { return f.pat.span; } + fn get_span(f: &ast::field_pat) -> codemap::span { return f.pat.span; } commasep_cmnt(s, consistent, *fields, |s, f| print_field(s,f,refutable), get_span); @@ -1598,7 +1597,7 @@ pub fn print_pat(s: @ps, pat: @ast::pat, refutable: bool) { } ast::pat_tup(ref elts) => { popen(s); - commasep(s, inconsistent, *elts, |s, p| print_pat(s, p, refutable)); + commasep(s, inconsistent, *elts, |s, &p| print_pat(s, p, refutable)); if elts.len() == 1 { word(s.s, ","); } @@ -1625,7 +1624,7 @@ pub fn print_pat(s: @ps, pat: @ast::pat, refutable: bool) { } ast::pat_vec(ref before, slice, ref after) => { word(s.s, "["); - do commasep(s, inconsistent, *before) |s, p| { + do commasep(s, inconsistent, *before) |s, &p| { print_pat(s, p, refutable); } for slice.iter().advance |&p| { @@ -1634,7 +1633,7 @@ pub fn print_pat(s: @ps, pat: @ast::pat, refutable: bool) { print_pat(s, p, refutable); if !after.is_empty() { word_space(s, ","); } } - do commasep(s, inconsistent, *after) |s, p| { + do commasep(s, inconsistent, *after) |s, &p| { print_pat(s, p, refutable); } word(s.s, "]"); @@ -1643,8 +1642,8 @@ pub fn print_pat(s: @ps, pat: @ast::pat, refutable: bool) { (s.ann.post)(ann_node); } -pub fn explicit_self_to_str(explicit_self: ast::explicit_self_, intr: @ident_interner) -> ~str { - to_str(explicit_self, |a, b| { print_explicit_self(a, b); () }, intr) +pub fn explicit_self_to_str(explicit_self: &ast::explicit_self_, intr: @ident_interner) -> ~str { + to_str(explicit_self, |a, &b| { print_explicit_self(a, b); () }, intr) } // Returns whether it printed anything @@ -1748,7 +1747,7 @@ pub fn print_bounds(s: @ps, bounds: &OptVec, } match *bound { - TraitTyParamBound(tref) => print_trait_ref(s, tref), + TraitTyParamBound(ref tref) => print_trait_ref(s, tref), RegionTyParamBound => word(s.s, "'static"), } } @@ -1784,12 +1783,12 @@ pub fn print_generics(s: @ps, generics: &ast::Generics) { } commasep(s, inconsistent, ints, - |s, i| print_item(s, generics, i)); + |s, &i| print_item(s, generics, i)); word(s.s, ">"); } } -pub fn print_meta_item(s: @ps, item: @ast::meta_item) { +pub fn print_meta_item(s: @ps, item: &ast::meta_item) { ibox(s, indent_unit); match item.node { ast::meta_word(name) => word(s.s, name), @@ -1804,8 +1803,8 @@ pub fn print_meta_item(s: @ps, item: @ast::meta_item) { commasep( s, consistent, - /* FIXME (#2543) */ copy *items, - print_meta_item + items.as_slice(), + |p, &i| print_meta_item(p, i) ); pclose(s); } @@ -1813,7 +1812,7 @@ pub fn print_meta_item(s: @ps, item: @ast::meta_item) { end(s); } -pub fn print_view_path(s: @ps, vp: @ast::view_path) { +pub fn print_view_path(s: @ps, vp: &ast::view_path) { match vp.node { ast::view_path_simple(ident, ref path, _) => { if path.idents[path.idents.len()-1u] != ident { @@ -1841,7 +1840,7 @@ pub fn print_view_path(s: @ps, vp: @ast::view_path) { } pub fn print_view_paths(s: @ps, vps: &[@ast::view_path]) { - commasep(s, inconsistent, vps, print_view_path); + commasep(s, inconsistent, vps, |p, &vp| print_view_path(p, vp)); } pub fn print_view_item(s: @ps, item: &ast::view_item) { @@ -1855,7 +1854,7 @@ pub fn print_view_item(s: @ps, item: &ast::view_item) { print_ident(s, id); if !mta.is_empty() { popen(s); - commasep(s, consistent, *mta, print_meta_item); + commasep(s, consistent, *mta, |p, &i| print_meta_item(p, i)); pclose(s); } } @@ -2003,7 +2002,7 @@ pub fn print_remaining_comments(s: @ps) { } } -pub fn print_literal(s: @ps, lit: @ast::lit) { +pub fn print_literal(s: @ps, lit: &ast::lit) { maybe_print_comment(s, lit.span.lo); match next_lit(s, lit.span.lo) { Some(ref ltrl) => { @@ -2056,7 +2055,7 @@ pub fn print_literal(s: @ps, lit: @ast::lit) { } } -pub fn lit_to_str(l: @ast::lit) -> ~str { +pub fn lit_to_str(l: &ast::lit) -> ~str { return to_str(l, print_literal, parse::token::mk_fake_ident_interner()); } @@ -2139,10 +2138,10 @@ pub fn print_string(s: @ps, st: &str) { word(s.s, "\""); } -pub fn to_str(t: T, f: @fn(@ps, T), intr: @ident_interner) -> ~str { +pub fn to_str(t: &T, f: &fn(@ps, &T), intr: @ident_interner) -> ~str { do io::with_str_writer |wr| { let s = rust_printer(wr, intr); - f(s, copy t); + f(s, t); eof(s.s); } } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 1e615ccb7775..4be9ef13db27 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -183,7 +183,7 @@ pub fn visit_item(i: &item, (e, v): (E, vt)) { } item_impl(ref tps, ref traits, ty, ref methods) => { (v.visit_generics)(tps, (copy e, v)); - for traits.iter().advance |&p| { + for traits.iter().advance |p| { visit_trait_ref(p, (copy e, v)); } (v.visit_ty)(ty, (copy e, v)); @@ -336,7 +336,7 @@ pub fn visit_ty_param_bounds(bounds: &OptVec, (e, v): (E, vt)) { for bounds.iter().advance |bound| { match *bound { - TraitTyParamBound(ty) => visit_trait_ref(ty, (copy e, v)), + TraitTyParamBound(ref ty) => visit_trait_ref(ty, (copy e, v)), RegionTyParamBound => {} } } From 46a1f54666dbeb9a926c75b380f62571963cbacc Mon Sep 17 00:00:00 2001 From: James Miller Date: Sat, 6 Jul 2013 13:38:56 +1200 Subject: [PATCH 77/93] De-manage OptVec --- src/librustc/metadata/encoder.rs | 2 +- src/librustc/middle/kind.rs | 2 +- src/librustc/middle/region.rs | 4 ++-- src/librustc/middle/resolve.rs | 2 +- src/librustc/middle/typeck/astconv.rs | 4 ++-- src/librustc/middle/typeck/collect.rs | 4 ++-- src/libsyntax/ast.rs | 4 ++-- src/libsyntax/ext/build.rs | 18 ++++++++---------- src/libsyntax/ext/deriving/generic.rs | 5 ++--- src/libsyntax/ext/deriving/ty.rs | 8 +++----- src/libsyntax/ext/pipes/pipec.rs | 27 +++++++++++++-------------- src/libsyntax/ext/pipes/proto.rs | 2 +- src/libsyntax/fold.rs | 9 +++++---- src/libsyntax/opt_vec.rs | 9 ++++++++- src/libsyntax/parse/parser.rs | 6 +++--- src/libsyntax/print/pprust.rs | 4 ++-- src/libsyntax/visit.rs | 4 ++-- 17 files changed, 58 insertions(+), 56 deletions(-) diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 9b4c39b3fc78..8273b3e663a4 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1014,7 +1014,7 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_name(ecx, ebml_w, item.ident); encode_attributes(ebml_w, item.attrs); match ty.node { - ast::ty_path(ref path, bounds, _) if path.idents.len() == 1 => { + ast::ty_path(ref path, ref bounds, _) if path.idents.len() == 1 => { assert!(bounds.is_none()); encode_impl_type_basename(ecx, ebml_w, ast_util::path_to_ident(path)); diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index 0c493fe9e81c..0bc7a4a01141 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -125,7 +125,7 @@ fn check_item(item: @item, (cx, visitor): (Context, visit::vt)) { if cx.tcx.lang_items.drop_trait() == trait_def_id { // Yes, it's a destructor. match self_type.node { - ty_path(_, bounds, path_node_id) => { + ty_path(_, ref bounds, path_node_id) => { assert!(bounds.is_none()); let struct_def = cx.tcx.def_map.get_copy( &path_node_id); diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index a5b64ea42684..f76d9541baab 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -784,7 +784,7 @@ fn determine_rp_in_ty(ty: @ast::Ty, // then check whether it is region-parameterized and consider // that as a direct dependency. match ty.node { - ast::ty_path(ref path, _bounds, id) => { + ast::ty_path(ref path, _, id) => { match cx.def_map.find(&id) { Some(&ast::def_ty(did)) | Some(&ast::def_trait(did)) | @@ -820,7 +820,7 @@ fn determine_rp_in_ty(ty: @ast::Ty, visit_mt(mt, (cx, visitor)); } - ast::ty_path(ref path, _bounds, _) => { + ast::ty_path(ref path, _, _) => { // type parameters are---for now, anyway---always invariant do cx.with_ambient_variance(rv_invariant) { for path.types.iter().advance |tp| { diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 3b90d72deb12..99ec1ccb1f1e 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -4117,7 +4117,7 @@ impl Resolver { // Like path expressions, the interpretation of path types depends // on whether the path has multiple elements in it or not. - ty_path(ref path, bounds, path_id) => { + ty_path(ref path, ref bounds, path_id) => { // This is a path in the type namespace. Walk through scopes // scopes looking for it. let mut result_def = None; diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index e224654f2d35..6aac077bbd9a 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -276,7 +276,7 @@ pub fn ast_ty_to_ty( } return ty::mk_evec(tcx, mt, vst); } - ast::ty_path(ref path, bounds, id) => { + ast::ty_path(ref path, ref bounds, id) => { // Note that the "bounds must be empty if path is not a trait" // restriction is enforced in the below case for ty_path, which // will run after this as long as the path isn't a trait. @@ -405,7 +405,7 @@ pub fn ast_ty_to_ty( ast_ty.span); ty::mk_closure(tcx, fn_decl) } - ast::ty_path(ref path, bounds, id) => { + ast::ty_path(ref path, ref bounds, id) => { let a_def = match tcx.def_map.find(&id) { None => tcx.sess.span_fatal( ast_ty.span, fmt!("unbound path %s", diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 60f97a0ae0a0..edd90be26474 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -1149,7 +1149,7 @@ pub fn ty_generics(ccx: &CrateCtxt, let param_ty = ty::param_ty {idx: base_index + offset, def_id: local_def(param.id)}; let bounds = @compute_bounds(ccx, rp, generics, - param_ty, param.bounds); + param_ty, ¶m.bounds); let def = ty::TypeParameterDef { def_id: local_def(param.id), bounds: bounds @@ -1167,7 +1167,7 @@ pub fn ty_generics(ccx: &CrateCtxt, rp: Option, generics: &ast::Generics, param_ty: ty::param_ty, - ast_bounds: @OptVec) -> ty::ParamBounds + ast_bounds: &OptVec) -> ty::ParamBounds { /*! * diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index a222f03820fc..d0c8ff03e388 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -140,7 +140,7 @@ pub enum TyParamBound { pub struct TyParam { ident: ident, id: node_id, - bounds: @OptVec + bounds: OptVec } #[deriving(Eq, Encodable, Decodable,IterBytes)] @@ -734,7 +734,7 @@ pub enum ty_ { ty_closure(@TyClosure), ty_bare_fn(@TyBareFn), ty_tup(~[@Ty]), - ty_path(Path, @Option>, node_id), // for #7264; see above + ty_path(Path, Option>, node_id), // for #7264; see above ty_mac(mac), // ty_infer means the type should be inferred instead of it having been // specified. This should only appear at the "top level" of a type and not diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 68b011e4fd7a..0388115d7ef9 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -46,7 +46,7 @@ pub trait AstBuilder { fn ty_mt(&self, ty: @ast::Ty, mutbl: ast::mutability) -> ast::mt; fn ty(&self, span: span, ty: ast::ty_) -> @ast::Ty; - fn ty_path(&self, ast::Path, @Option>) -> @ast::Ty; + fn ty_path(&self, ast::Path, Option>) -> @ast::Ty; fn ty_ident(&self, span: span, idents: ast::ident) -> @ast::Ty; fn ty_rptr(&self, span: span, @@ -66,7 +66,7 @@ pub trait AstBuilder { fn ty_field_imm(&self, span: span, name: ident, ty: @ast::Ty) -> ast::ty_field; fn strip_bounds(&self, bounds: &Generics) -> Generics; - fn typaram(&self, id: ast::ident, bounds: @OptVec) -> ast::TyParam; + fn typaram(&self, id: ast::ident, bounds: OptVec) -> ast::TyParam; fn trait_ref(&self, path: ast::Path) -> ast::trait_ref; fn typarambound(&self, path: ast::Path) -> ast::TyParamBound; @@ -265,7 +265,7 @@ impl AstBuilder for @ExtCtxt { } } - fn ty_path(&self, path: ast::Path, bounds: @Option>) + fn ty_path(&self, path: ast::Path, bounds: Option>) -> @ast::Ty { self.ty(path.span, ast::ty_path(path, bounds, self.next_id())) @@ -275,7 +275,7 @@ impl AstBuilder for @ExtCtxt { // to generate a bounded existential trait type. fn ty_ident(&self, span: span, ident: ast::ident) -> @ast::Ty { - self.ty_path(self.path_ident(span, ident), @None) + self.ty_path(self.path_ident(span, ident), None) } fn ty_rptr(&self, @@ -305,8 +305,7 @@ impl AstBuilder for @ExtCtxt { self.ident_of("Option") ], None, - ~[ ty ]), - @None) + ~[ ty ]), None) } fn ty_field_imm(&self, span: span, name: ident, ty: @ast::Ty) -> ast::ty_field { @@ -329,7 +328,7 @@ impl AstBuilder for @ExtCtxt { } } - fn typaram(&self, id: ast::ident, bounds: @OptVec) -> ast::TyParam { + fn typaram(&self, id: ast::ident, bounds: OptVec) -> ast::TyParam { ast::TyParam { ident: id, id: self.next_id(), bounds: bounds } } @@ -344,13 +343,12 @@ impl AstBuilder for @ExtCtxt { fn ty_vars_global(&self, ty_params: &OptVec) -> ~[@ast::Ty] { opt_vec::take_vec( ty_params.map(|p| self.ty_path( - self.path_global(dummy_sp(), ~[p.ident]), @None))) + self.path_global(dummy_sp(), ~[p.ident]), None))) } fn strip_bounds(&self, generics: &Generics) -> Generics { - let no_bounds = @opt_vec::Empty; let new_params = do generics.ty_params.map |ty_param| { - ast::TyParam { bounds: no_bounds, ..copy *ty_param } + ast::TyParam { bounds: opt_vec::Empty, ..copy *ty_param } }; Generics { ty_params: new_params, diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index 8bd74b96afc1..10282cb6f0ae 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -337,7 +337,7 @@ impl<'self> TraitDef<'self> { // require the current trait bounds.push(cx.typarambound(copy trait_path)); - trait_generics.ty_params.push(cx.typaram(ty_param.ident, @bounds)); + trait_generics.ty_params.push(cx.typaram(ty_param.ident, bounds)); } // Create the reference to the trait. @@ -356,8 +356,7 @@ impl<'self> TraitDef<'self> { // Create the type of `self`. let self_type = cx.ty_path(cx.path_all(span, false, ~[ type_ident ], self_lifetime, - opt_vec::take_vec(self_ty_params)), - @None); + opt_vec::take_vec(self_ty_params)), None); let doc_attr = cx.attribute( span, diff --git a/src/libsyntax/ext/deriving/ty.rs b/src/libsyntax/ext/deriving/ty.rs index 2a60a20b8722..c820371714bf 100644 --- a/src/libsyntax/ext/deriving/ty.rs +++ b/src/libsyntax/ext/deriving/ty.rs @@ -62,8 +62,7 @@ impl<'self> Path<'self> { self_ty: ident, self_generics: &Generics) -> @ast::Ty { - cx.ty_path(self.to_path(cx, span, - self_ty, self_generics), @None) + cx.ty_path(self.to_path(cx, span, self_ty, self_generics), None) } pub fn to_path(&self, cx: @ExtCtxt, @@ -142,8 +141,7 @@ impl<'self> Ty<'self> { } Literal(ref p) => { p.to_ty(cx, span, self_ty, self_generics) } Self => { - cx.ty_path(self.to_path(cx, span, self_ty, self_generics), - @None) + cx.ty_path(self.to_path(cx, span, self_ty, self_generics), None) } Tuple(ref fields) => { let ty = if fields.is_empty() { @@ -194,7 +192,7 @@ fn mk_ty_param(cx: @ExtCtxt, span: span, name: &str, bounds: &[Path], let path = b.to_path(cx, span, self_ident, self_generics); cx.typarambound(path) }); - cx.typaram(cx.ident_of(name), @bounds) + cx.typaram(cx.ident_of(name), bounds) } fn mk_generics(lifetimes: ~[ast::Lifetime], ty_params: ~[ast::TyParam]) -> Generics { diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index 0e24725ea990..57174f216fe5 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -60,7 +60,7 @@ impl gen_send for message { let pipe_ty = cx.ty_path( path(~[this.data_name()], span) - .add_tys(cx.ty_vars(&this.generics.ty_params)), @None); + .add_tys(cx.ty_vars(&this.generics.ty_params)), None); let args_ast = vec::append( ~[cx.arg(span, cx.ident_of("pipe"), pipe_ty)], args_ast); @@ -117,7 +117,7 @@ impl gen_send for message { let mut rty = cx.ty_path(path(~[next.data_name()], span) - .add_tys(copy next_state.tys), @None); + .add_tys(copy next_state.tys), None); if try { rty = cx.ty_option(rty); } @@ -145,7 +145,7 @@ impl gen_send for message { cx.ty_path( path(~[this.data_name()], span) .add_tys(cx.ty_vars( - &this.generics.ty_params)), @None))], + &this.generics.ty_params)), None))], args_ast); let message_args = if arg_names.len() == 0 { @@ -191,7 +191,7 @@ impl gen_send for message { fn to_ty(&mut self, cx: @ExtCtxt) -> @ast::Ty { cx.ty_path(path(~[cx.ident_of(self.name())], self.span()) - .add_tys(cx.ty_vars(&self.get_generics().ty_params)), @None) + .add_tys(cx.ty_vars(&self.get_generics().ty_params)), None) } } @@ -225,7 +225,7 @@ impl to_type_decls for state { cx.ty_path( path(~[cx.ident_of(dir), cx.ident_of(next_name)], span) - .add_tys(copy next_state.tys), @None)) + .add_tys(copy next_state.tys), None)) } None => tys }; @@ -278,8 +278,7 @@ impl to_type_decls for state { self.data_name()], dummy_sp()) .add_tys(cx.ty_vars( - &self.generics.ty_params)), @None)), - @None), + &self.generics.ty_params)), None)), None), cx.strip_bounds(&self.generics))); } else { @@ -298,8 +297,8 @@ impl to_type_decls for state { self.data_name()], dummy_sp()) .add_tys(cx.ty_vars_global( - &self.generics.ty_params)), @None), - self.proto.buffer_ty_path(cx)]), @None), + &self.generics.ty_params)), None), + self.proto.buffer_ty_path(cx)]), None), cx.strip_bounds(&self.generics))); }; items @@ -372,10 +371,10 @@ impl gen_init for protocol { fn buffer_ty_path(&self, cx: @ExtCtxt) -> @ast::Ty { let mut params: OptVec = opt_vec::Empty; - for (copy self.states).iter().advance |s| { + for self.states.iter().advance |s| { for s.generics.ty_params.iter().advance |tp| { match params.iter().find_(|tpp| tp.ident == tpp.ident) { - None => params.push(*tp), + None => params.push(copy *tp), _ => () } } @@ -384,16 +383,16 @@ impl gen_init for protocol { cx.ty_path(path(~[cx.ident_of("super"), cx.ident_of("__Buffer")], copy self.span) - .add_tys(cx.ty_vars_global(¶ms)), @None) + .add_tys(cx.ty_vars_global(¶ms)), None) } fn gen_buffer_type(&self, cx: @ExtCtxt) -> @ast::item { let ext_cx = cx; let mut params: OptVec = opt_vec::Empty; - let fields = do (copy self.states).iter().transform |s| { + let fields = do self.states.iter().transform |s| { for s.generics.ty_params.iter().advance |tp| { match params.iter().find_(|tpp| tp.ident == tpp.ident) { - None => params.push(*tp), + None => params.push(copy *tp), _ => () } } diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs index 0525c6664780..f3d7158de526 100644 --- a/src/libsyntax/ext/pipes/proto.rs +++ b/src/libsyntax/ext/pipes/proto.rs @@ -99,7 +99,7 @@ impl state_ { pub fn to_ty(&self, cx: @ExtCtxt) -> @ast::Ty { cx.ty_path (path(~[cx.ident_of(self.name)],self.span).add_tys( - cx.ty_vars(&self.generics.ty_params)), @None) + cx.ty_vars(&self.generics.ty_params)), None) } /// Iterate over the states that can be reached in one message diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 85eb499069bd..c6592d36e409 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -171,12 +171,13 @@ pub fn fold_ty_param(tp: TyParam, fld: @ast_fold) -> TyParam { TyParam {ident: tp.ident, id: fld.new_id(tp.id), - bounds: @tp.bounds.map(|x| fold_ty_param_bound(x, fld))} + bounds: tp.bounds.map(|x| fold_ty_param_bound(x, fld))} } pub fn fold_ty_params(tps: &OptVec, fld: @ast_fold) -> OptVec { - tps.map(|tp| fold_ty_param(*tp, fld)) + let tps = /*bad*/ copy *tps; + tps.map_consume(|tp| fold_ty_param(tp, fld)) } pub fn fold_lifetime(l: &Lifetime, @@ -682,8 +683,8 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ { }) } ty_tup(ref tys) => ty_tup(tys.map(|ty| fld.fold_ty(*ty))), - ty_path(ref path, bounds, id) => - ty_path(fld.fold_path(path), @fold_opt_bounds(bounds, fld), fld.new_id(id)), + ty_path(ref path, ref bounds, id) => + ty_path(fld.fold_path(path), fold_opt_bounds(bounds, fld), fld.new_id(id)), ty_fixed_length_vec(ref mt, e) => { ty_fixed_length_vec( fold_mt(mt, fld), diff --git a/src/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs index 8e2da3d6eb1a..ba3b72ec1944 100644 --- a/src/libsyntax/opt_vec.rs +++ b/src/libsyntax/opt_vec.rs @@ -16,7 +16,7 @@ * other useful things like `push()` and `len()`. */ -use std::vec::VecIterator; +use std::vec::{VecIterator}; #[deriving(Encodable, Decodable,IterBytes)] pub enum OptVec { @@ -58,6 +58,13 @@ impl OptVec { } } + fn map_consume(self, op: &fn(T) -> U) -> OptVec { + match self { + Empty => Empty, + Vec(v) => Vec(v.consume_iter().transform(op).collect()) + } + } + fn get<'a>(&'a self, i: uint) -> &'a T { match *self { Empty => fail!("Invalid index %u", i), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 8f1bffdaa789..4c662cc46213 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -968,7 +968,7 @@ impl Parser { || is_ident_or_path(self.token) { // NAMED TYPE let (path, bounds) = self.parse_type_path(); - ty_path(path, @bounds, self.get_id()) + ty_path(path, bounds, self.get_id()) } else { self.fatal(fmt!("expected type, found token %?", *self.token)); @@ -3213,7 +3213,7 @@ impl Parser { let ident = self.parse_ident(); let opt_bounds = self.parse_optional_ty_param_bounds(); // For typarams we don't care about the difference b/w "" and "". - let bounds = @opt_bounds.get_or_default(opt_vec::Empty); + let bounds = opt_bounds.get_or_default(opt_vec::Empty); ast::TyParam { ident: ident, id: self.get_id(), bounds: bounds } } @@ -3565,7 +3565,7 @@ impl Parser { let opt_trait = if could_be_trait && self.eat_keyword(keywords::For) { // New-style trait. Reinterpret the type as a trait. let opt_trait_ref = match ty.node { - ty_path(ref path, @None, node_id) => { + ty_path(ref path, None, node_id) => { Some(trait_ref { path: /* bad */ copy *path, ref_id: node_id diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index d90055caffb9..d054f9278945 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -418,7 +418,7 @@ pub fn print_type(s: @ps, ty: &ast::Ty) { f.purity, f.onceness, &f.decl, None, &f.bounds, Some(&generics), None); } - ast::ty_path(ref path, bounds, _) => print_bounded_path(s, path, bounds), + ast::ty_path(ref path, ref bounds, _) => print_bounded_path(s, path, bounds), ast::ty_fixed_length_vec(ref mt, v) => { word(s.s, "["); match mt.mutbl { @@ -1773,7 +1773,7 @@ pub fn print_generics(s: @ps, generics: &ast::Generics) { let idx = idx - generics.lifetimes.len(); let param = generics.ty_params.get(idx); print_ident(s, param.ident); - print_bounds(s, param.bounds, false); + print_bounds(s, ¶m.bounds, false); } } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 4be9ef13db27..b513b68b74f8 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -252,7 +252,7 @@ pub fn visit_ty(t: &Ty, (e, v): (E, vt)) { for f.decl.inputs.iter().advance |a| { (v.visit_ty)(a.ty, (copy e, v)); } (v.visit_ty)(f.decl.output, (e, v)); }, - ty_path(ref p, bounds, _) => { + ty_path(ref p, ref bounds, _) => { visit_path(p, (copy e, v)); do bounds.map |bounds| { visit_ty_param_bounds(bounds, (copy e, v)); @@ -344,7 +344,7 @@ pub fn visit_ty_param_bounds(bounds: &OptVec, pub fn visit_generics(generics: &Generics, (e, v): (E, vt)) { for generics.ty_params.iter().advance |tp| { - visit_ty_param_bounds(tp.bounds, (copy e, v)); + visit_ty_param_bounds(&tp.bounds, (copy e, v)); } } From 47eca2113c5c55a4ffbb8c11a38c8ca7a79a1d72 Mon Sep 17 00:00:00 2001 From: James Miller Date: Sat, 6 Jul 2013 16:57:11 +1200 Subject: [PATCH 78/93] De-share ast::Ty --- src/librustc/front/config.rs | 4 +- src/librustc/metadata/encoder.rs | 2 +- src/librustc/middle/kind.rs | 4 +- src/librustc/middle/lint.rs | 6 +- src/librustc/middle/region.rs | 18 ++--- src/librustc/middle/resolve.rs | 34 ++++---- src/librustc/middle/trans/base.rs | 6 +- src/librustc/middle/trans/debuginfo.rs | 20 ++--- src/librustc/middle/typeck/astconv.rs | 16 ++-- src/librustc/middle/typeck/check/mod.rs | 18 ++--- src/librustc/middle/typeck/coherence.rs | 4 +- src/librustc/middle/typeck/collect.rs | 16 ++-- src/libsyntax/ast.rs | 30 +++---- src/libsyntax/ext/build.rs | 103 ++++++++++++------------ src/libsyntax/ext/deriving/generic.rs | 6 +- src/libsyntax/ext/deriving/ty.rs | 4 +- src/libsyntax/ext/pipes/ast_builder.rs | 8 +- src/libsyntax/ext/pipes/check.rs | 2 +- src/libsyntax/ext/pipes/pipec.rs | 12 +-- src/libsyntax/ext/pipes/proto.rs | 10 +-- src/libsyntax/ext/quote.rs | 10 +-- src/libsyntax/fold.rs | 48 +++++------ src/libsyntax/parse/parser.rs | 34 ++++---- src/libsyntax/parse/token.rs | 2 +- src/libsyntax/print/pprust.rs | 40 ++++----- src/libsyntax/visit.rs | 54 ++++++------- 26 files changed, 256 insertions(+), 255 deletions(-) diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs index 0f71eeff5a2f..df829d5e2096 100644 --- a/src/librustc/front/config.rs +++ b/src/librustc/front/config.rs @@ -98,10 +98,10 @@ fn fold_foreign_mod( fn fold_item_underscore(cx: @Context, item: &ast::item_, fld: @fold::ast_fold) -> ast::item_ { let item = match *item { - ast::item_impl(ref a, ref b, c, ref methods) => { + ast::item_impl(ref a, ref b, ref c, ref methods) => { let methods = methods.iter().filter(|m| method_in_cfg(cx, **m)) .transform(|x| *x).collect(); - ast::item_impl(/*bad*/ copy *a, /*bad*/ copy *b, c, methods) + ast::item_impl(/*bad*/ copy *a, /*bad*/ copy *b, /*bad*/ copy *c, methods) } ast::item_trait(ref a, ref b, ref methods) => { let methods = methods.iter().filter(|m| trait_method_in_cfg(cx, *m) ) diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 8273b3e663a4..a9f3200af128 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1003,7 +1003,7 @@ fn encode_info_for_item(ecx: &EncodeContext, index); } } - item_impl(ref generics, ref opt_trait, ty, ref methods) => { + item_impl(ref generics, ref opt_trait, ref ty, ref methods) => { add_to_index(); ebml_w.start_tag(tag_items_data_item); encode_def_id(ebml_w, local_def(item.id)); diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index 0bc7a4a01141..335a54a97535 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -117,7 +117,7 @@ fn check_item(item: @item, (cx, visitor): (Context, visit::vt)) { // If this is a destructor, check kinds. if !attrs_contains_name(item.attrs, "unsafe_destructor") { match item.node { - item_impl(_, Some(ref trait_ref), self_type, _) => { + item_impl(_, Some(ref trait_ref), ref self_type, _) => { match cx.tcx.def_map.find(&trait_ref.ref_id) { None => cx.tcx.sess.bug("trait ref not in def map!"), Some(&trait_def) => { @@ -321,7 +321,7 @@ pub fn check_expr(e: @expr, (cx, v): (Context, visit::vt)) { visit::visit_expr(e, (cx, v)); } -fn check_ty(aty: @Ty, (cx, v): (Context, visit::vt)) { +fn check_ty(aty: &Ty, (cx, v): (Context, visit::vt)) { match aty.node { ty_path(_, _, id) => { let r = cx.tcx.node_type_substs.find(&id); diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index c39b676b97f0..0dce9c69bfdb 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -747,9 +747,9 @@ fn check_item_ctypes(cx: &Context, it: &ast::item) { fn check_foreign_fn(cx: &Context, decl: &ast::fn_decl) { for decl.inputs.iter().advance |in| { - check_ty(cx, in.ty); + check_ty(cx, &in.ty); } - check_ty(cx, decl.output) + check_ty(cx, &decl.output) } match it.node { @@ -759,7 +759,7 @@ fn check_item_ctypes(cx: &Context, it: &ast::item) { ast::foreign_item_fn(ref decl, _, _) => { check_foreign_fn(cx, decl); } - ast::foreign_item_static(t, _) => { check_ty(cx, t); } + ast::foreign_item_static(ref t, _) => { check_ty(cx, t); } } } } diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index f76d9541baab..b1b2a0083acc 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -713,10 +713,10 @@ fn determine_rp_in_fn(fk: &visit::fn_kind, do cx.with(cx.item_id, false) { do cx.with_ambient_variance(rv_contravariant) { for decl.inputs.iter().advance |a| { - (visitor.visit_ty)(a.ty, (cx, visitor)); + (visitor.visit_ty)(&a.ty, (cx, visitor)); } } - (visitor.visit_ty)(decl.output, (cx, visitor)); + (visitor.visit_ty)(&decl.output, (cx, visitor)); let generics = visit::generics_of_fn(fk); (visitor.visit_generics)(&generics, (cx, visitor)); (visitor.visit_block)(body, (cx, visitor)); @@ -731,7 +731,7 @@ fn determine_rp_in_ty_method(ty_m: &ast::ty_method, } } -fn determine_rp_in_ty(ty: @ast::Ty, +fn determine_rp_in_ty(ty: &ast::Ty, (cx, visitor): (@mut DetermineRpCtxt, visit::vt<@mut DetermineRpCtxt>)) { // we are only interested in types that will require an item to @@ -815,8 +815,8 @@ fn determine_rp_in_ty(ty: @ast::Ty, } match ty.node { - ast::ty_box(mt) | ast::ty_uniq(mt) | ast::ty_vec(mt) | - ast::ty_rptr(_, mt) | ast::ty_ptr(mt) => { + ast::ty_box(ref mt) | ast::ty_uniq(ref mt) | ast::ty_vec(ref mt) | + ast::ty_rptr(_, ref mt) | ast::ty_ptr(ref mt) => { visit_mt(mt, (cx, visitor)); } @@ -824,7 +824,7 @@ fn determine_rp_in_ty(ty: @ast::Ty, // type parameters are---for now, anyway---always invariant do cx.with_ambient_variance(rv_invariant) { for path.types.iter().advance |tp| { - (visitor.visit_ty)(*tp, (cx, visitor)); + (visitor.visit_ty)(tp, (cx, visitor)); } } } @@ -837,10 +837,10 @@ fn determine_rp_in_ty(ty: @ast::Ty, // parameters are contravariant do cx.with_ambient_variance(rv_contravariant) { for decl.inputs.iter().advance |a| { - (visitor.visit_ty)(a.ty, (cx, visitor)); + (visitor.visit_ty)(&a.ty, (cx, visitor)); } } - (visitor.visit_ty)(decl.output, (cx, visitor)); + (visitor.visit_ty)(&decl.output, (cx, visitor)); } } @@ -849,7 +849,7 @@ fn determine_rp_in_ty(ty: @ast::Ty, } } - fn visit_mt(mt: ast::mt, + fn visit_mt(mt: &ast::mt, (cx, visitor): (@mut DetermineRpCtxt, visit::vt<@mut DetermineRpCtxt>)) { // mutability is invariant diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 99ec1ccb1f1e..861c61e497aa 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -1233,7 +1233,7 @@ impl Resolver { visit_item(item, (new_parent, visitor)); } - item_impl(_, None, ty, ref methods) => { + item_impl(_, None, ref ty, ref methods) => { // If this implements an anonymous trait, then add all the // methods within to a new module, if the type was defined // within this module. @@ -1243,8 +1243,8 @@ impl Resolver { // the same module that declared the type. // Create the module and add all methods. - match *ty { - Ty { + match ty { + &Ty { node: ty_path(ref path, _, _), _ } if path.idents.len() == 1 => { @@ -1313,7 +1313,7 @@ impl Resolver { visit_item(item, (parent, visitor)); } - item_impl(_, Some(_), _ty, ref _methods) => { + item_impl(_, Some(_), _, _) => { visit_item(item, (parent, visitor)); } @@ -3534,7 +3534,7 @@ impl Resolver { item_impl(ref generics, ref implemented_traits, - self_type, + ref self_type, ref methods) => { self.resolve_implementation(item.id, generics, @@ -3585,10 +3585,10 @@ impl Resolver { visitor); for ty_m.decl.inputs.iter().advance |argument| { - self.resolve_type(argument.ty, visitor); + self.resolve_type(&argument.ty, visitor); } - self.resolve_type(ty_m.decl.output, visitor); + self.resolve_type(&ty_m.decl.output, visitor); } } provided(m) => { @@ -3778,12 +3778,12 @@ impl Resolver { None, visitor); - self.resolve_type(argument.ty, visitor); + self.resolve_type(&argument.ty, visitor); debug!("(resolving function) recorded argument"); } - self.resolve_type(declaration.output, visitor); + self.resolve_type(&declaration.output, visitor); } } @@ -3878,7 +3878,7 @@ impl Resolver { // Resolve fields. for fields.iter().advance |field| { - self.resolve_type(field.node.ty, visitor); + self.resolve_type(&field.node.ty, visitor); } } } @@ -3914,7 +3914,7 @@ impl Resolver { id: node_id, generics: &Generics, opt_trait_reference: &Option, - self_type: @Ty, + self_type: &Ty, methods: &[@method], visitor: ResolveVisitor) { // If applicable, create a rib for the type parameters. @@ -4001,7 +4001,7 @@ impl Resolver { let mutability = if local.node.is_mutbl {Mutable} else {Immutable}; // Resolve the type. - self.resolve_type(local.node.ty, visitor); + self.resolve_type(&local.node.ty, visitor); // Resolve the initializer, if necessary. match local.node.init { @@ -4112,7 +4112,7 @@ impl Resolver { debug!("(resolving block) leaving block"); } - pub fn resolve_type(@mut self, ty: @Ty, visitor: ResolveVisitor) { + pub fn resolve_type(@mut self, ty: &Ty, visitor: ResolveVisitor) { match ty.node { // Like path expressions, the interpretation of path types depends // on whether the path has multiple elements in it or not. @@ -4334,7 +4334,7 @@ impl Resolver { // Check the types in the path pattern. for path.types.iter().advance |ty| { - self.resolve_type(*ty, visitor); + self.resolve_type(ty, visitor); } } @@ -4367,7 +4367,7 @@ impl Resolver { // Check the types in the path pattern. for path.types.iter().advance |ty| { - self.resolve_type(*ty, visitor); + self.resolve_type(ty, visitor); } } @@ -4396,7 +4396,7 @@ impl Resolver { // Check the types in the path pattern. for path.types.iter().advance |ty| { - self.resolve_type(*ty, visitor); + self.resolve_type(ty, visitor); } } @@ -4491,7 +4491,7 @@ impl Resolver { -> Option { // First, resolve the types. for path.types.iter().advance |ty| { - self.resolve_type(*ty, visitor); + self.resolve_type(ty, visitor); } if path.global { diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index e5edd43cf051..e6384ae4d0d3 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1737,7 +1737,7 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt, fcx.llargs.insert(arg_id, llarg); if fcx.ccx.sess.opts.extra_debuginfo && fcx_has_nonzero_span(fcx) { - debuginfo::create_arg(bcx, args[arg_n], args[arg_n].ty.span); + debuginfo::create_arg(bcx, &args[arg_n], args[arg_n].ty.span); } } @@ -1911,7 +1911,7 @@ pub fn trans_enum_variant(ccx: @mut CrateContext, let fn_args = do args.map |varg| { ast::arg { is_mutbl: false, - ty: varg.ty, + ty: copy varg.ty, pat: ast_util::ident_to_pat( ccx.tcx.sess.next_node_id(), codemap::dummy_sp(), @@ -1985,7 +1985,7 @@ pub fn trans_tuple_struct(ccx: @mut CrateContext, let fn_args = do fields.map |field| { ast::arg { is_mutbl: false, - ty: field.node.ty, + ty: copy field.node.ty, pat: ast_util::ident_to_pat(ccx.tcx.sess.next_node_id(), codemap::dummy_sp(), special_idents::arg), diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 32a71ea70197..fc73d8053798 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -182,7 +182,7 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { /// /// Adds the created metadata nodes directly to the crate's IR. /// The return value should be ignored if called from outside of the debuginfo module. -pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { +pub fn create_arg(bcx: block, arg: &ast::arg, span: span) -> Option { debug!("create_arg"); if true { // XXX create_arg disabled for now because "node_id_type(bcx, arg.id)" below blows @@ -259,23 +259,25 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { let fcx = &mut *fcx; let span = fcx.span.get(); - let (ident, ret_ty, id) = match cx.tcx.items.get_copy(&fcx.id) { - ast_map::node_item(item, _) => { + let fnitem = cx.tcx.items.get_copy(&fcx.id); + let (ident, ret_ty, id) = match fnitem { + ast_map::node_item(ref item, _) => { match item.node { - ast::item_fn(ref decl, _, _, _, _) => { - (item.ident, decl.output, item.id) + ast::item_fn(ast::fn_decl { output: ref ty, _}, _, _, _, _) => { + (item.ident, ty, item.id) } _ => fcx.ccx.sess.span_bug(item.span, "create_function: item bound to non-function") } } - ast_map::node_method(method, _, _) => { - (method.ident, method.decl.output, method.id) + ast_map::node_method(@ast::method { decl: ast::fn_decl { output: ref ty, _ }, + id: id, ident: ident, _}, _, _) => { + (ident, ty, id) } - ast_map::node_expr(expr) => { + ast_map::node_expr(ref expr) => { match expr.node { ast::expr_fn_block(ref decl, _) => { let name = gensym_name("fn"); - (name, decl.output, expr.id) + (name, &decl.output, expr.id) } _ => fcx.ccx.sess.span_bug(expr.span, "create_function: expected an expr_fn_block here") diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 6aac077bbd9a..9442eb0b8386 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -179,7 +179,7 @@ fn ast_path_substs( fmt!("wrong number of type arguments: expected %u but found %u", decl_generics.type_param_defs.len(), path.types.len())); } - let tps = path.types.map(|a_t| ast_ty_to_ty(this, rscope, *a_t)); + let tps = path.types.map(|a_t| ast_ty_to_ty(this, rscope, a_t)); substs {self_r:self_r, self_ty:self_ty, tps:tps} } @@ -377,7 +377,7 @@ pub fn ast_ty_to_ty( |tmt| ty::mk_rptr(tcx, r, tmt)) } ast::ty_tup(ref fields) => { - let flds = fields.map(|t| ast_ty_to_ty(this, rscope, *t)); + let flds = fields.map(|t| ast_ty_to_ty(this, rscope, t)); ty::mk_tup(tcx, flds) } ast::ty_bare_fn(ref bf) => { @@ -525,13 +525,13 @@ pub fn ty_of_arg( this: &AC, rscope: &RS, - a: ast::arg, + a: &ast::arg, expected_ty: Option) -> ty::t { match a.ty.node { ast::ty_infer if expected_ty.is_some() => expected_ty.get(), ast::ty_infer => this.ty_infer(a.ty.span), - _ => ast_ty_to_ty(this, rscope, a.ty), + _ => ast_ty_to_ty(this, rscope, &a.ty), } } @@ -621,11 +621,11 @@ fn ty_of_method_or_bare_fn( transform_self_ty(this, &rb, self_info) }); - let input_tys = decl.inputs.map(|a| ty_of_arg(this, &rb, *a, None)); + let input_tys = decl.inputs.map(|a| ty_of_arg(this, &rb, a, None)); let output_ty = match decl.output.node { ast::ty_infer => this.ty_infer(decl.output.span), - _ => ast_ty_to_ty(this, &rb, decl.output) + _ => ast_ty_to_ty(this, &rb, &decl.output) }; return (opt_transformed_self_ty, @@ -724,14 +724,14 @@ pub fn ty_of_closure( // were supplied if i < e.inputs.len() {Some(e.inputs[i])} else {None} }; - ty_of_arg(this, &rb, *a, expected_arg_ty) + ty_of_arg(this, &rb, a, expected_arg_ty) }.collect(); let expected_ret_ty = expected_sig.map(|e| e.output); let output_ty = match decl.output.node { ast::ty_infer if expected_ret_ty.is_some() => expected_ret_ty.get(), ast::ty_infer => this.ty_infer(decl.output.span), - _ => ast_ty_to_ty(this, &rb, decl.output) + _ => ast_ty_to_ty(this, &rb, &decl.output) }; ty::ClosureTy { diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index cd66c765a2d6..51159c0391a1 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -476,7 +476,7 @@ pub fn check_fn(ccx: @mut CrateCtxt, |local, (e, v)| { let o_ty = match local.node.ty.node { ast::ty_infer => None, - _ => Some(fcx.to_ty(local.node.ty)) + _ => Some(fcx.to_ty(&local.node.ty)) }; assign(local.node.id, o_ty); debug!("Local variable %s is assigned type %s", @@ -624,7 +624,7 @@ pub fn check_item(ccx: @mut CrateCtxt, it: @ast::item) { ast::item_struct(*) => { check_struct(ccx, it.id, it.span); } - ast::item_ty(t, ref generics) => { + ast::item_ty(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); } @@ -790,7 +790,7 @@ impl FnCtxt { self.write_ty(node_id, ty::mk_err()); } - pub fn to_ty(&self, ast_t: @ast::Ty) -> ty::t { + pub fn to_ty(&self, ast_t: &ast::Ty) -> ty::t { ast_ty_to_ty(self, self, ast_t) } @@ -1381,7 +1381,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, rcvr: @ast::expr, method_name: ast::ident, args: &[@ast::expr], - tps: &[@ast::Ty], + tps: &[ast::Ty], sugar: ast::CallSugar) { check_expr(fcx, rcvr); @@ -1390,7 +1390,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, expr.span, fcx.expr_ty(rcvr)); - let tps = tps.map(|ast_ty| fcx.to_ty(*ast_ty)); + let tps = tps.map(|ast_ty| fcx.to_ty(ast_ty)); match method::lookup(fcx, expr, rcvr, @@ -1779,7 +1779,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, expr: @ast::expr, base: @ast::expr, field: ast::ident, - tys: &[@ast::Ty]) { + tys: &[ast::Ty]) { let tcx = fcx.ccx.tcx; let bot = check_expr(fcx, base); let expr_t = structurally_resolved_type(fcx, expr.span, @@ -1809,7 +1809,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, _ => () } - let tps = tys.iter().transform(|ty| fcx.to_ty(*ty)).collect::<~[ty::t]>(); + let tps : ~[ty::t] = tys.iter().transform(|ty| fcx.to_ty(ty)).collect(); match method::lookup(fcx, expr, base, @@ -2622,7 +2622,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, fcx.write_bot(id); } } - ast::expr_cast(e, t) => { + ast::expr_cast(e, ref t) => { check_expr(fcx, e); let t_1 = fcx.to_ty(t); let t_e = fcx.expr_ty(e); @@ -3336,7 +3336,7 @@ pub fn instantiate_path(fcx: @mut FnCtxt, (span, "not enough type parameters provided for this item"); fcx.infcx().next_ty_vars(ty_param_count) } else { - pth.types.map(|aty| fcx.to_ty(*aty)) + pth.types.map(|aty| fcx.to_ty(aty)) }; let substs = substs { self_r: self_r, self_ty: None, tps: tps }; diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index aef0e4b200b9..473d5b8e6e88 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -638,7 +638,7 @@ impl CoherenceChecker { // Then visit the module items. visit_mod(module_, item.span, item.id, ((), visitor)); } - item_impl(_, None, ast_ty, _) => { + item_impl(_, None, ref ast_ty, _) => { if !self.ast_type_is_defined_in_local_crate(ast_ty) { // This is an error. let session = self.crate_context.tcx.sess; @@ -725,7 +725,7 @@ impl CoherenceChecker { /// For coherence, when we have `impl Type`, we need to guarantee that /// `Type` is "local" to the crate. For our purposes, this means that it /// must precisely name some nominal type defined in this crate. - pub fn ast_type_is_defined_in_local_crate(&self, original_type: @ast::Ty) + pub fn ast_type_is_defined_in_local_crate(&self, original_type: &ast::Ty) -> bool { match original_type.node { ty_path(_, _, path_id) => { diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index edd90be26474..fb88f198231f 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -148,7 +148,7 @@ pub fn get_enum_variant_types(ccx: &CrateCtxt, match variant.node.kind { ast::tuple_variant_kind(ref args) if args.len() > 0 => { let rs = type_rscope(region_parameterization); - let input_tys = args.map(|va| ccx.to_ty(&rs, va.ty)); + let input_tys = args.map(|va| ccx.to_ty(&rs, &va.ty)); result_ty = Some(ty::mk_ctor_fn(tcx, input_tys, enum_ty)); } @@ -684,7 +684,7 @@ pub fn convert_field(ccx: &CrateCtxt, generics: &ast::Generics) { let region_parameterization = RegionParameterization::from_variance_and_generics(rp, generics); - let tt = ccx.to_ty(&type_rscope(region_parameterization), v.node.ty); + let tt = ccx.to_ty(&type_rscope(region_parameterization), &v.node.ty); write_ty_to_tcx(ccx.tcx, v.node.id, tt); /* add the field to the tcache */ ccx.tcx.tcache.insert(local_def(v.node.id), @@ -813,7 +813,7 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::item) { generics, rp); } - ast::item_impl(ref generics, ref opt_trait_ref, selfty, ref ms) => { + ast::item_impl(ref generics, ref opt_trait_ref, ref selfty, ref ms) => { let i_ty_generics = ty_generics(ccx, rp, generics, 0); let region_parameterization = RegionParameterization::from_variance_and_generics(rp, generics); @@ -1031,7 +1031,7 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::item) } let rp = tcx.region_paramd_items.find(&it.id).map_consume(|x| *x); match it.node { - ast::item_static(t, _, _) => { + ast::item_static(ref t, _, _) => { let typ = ccx.to_ty(&empty_rscope, t); let tpt = no_params(typ); tcx.tcache.insert(local_def(it.id), tpt); @@ -1060,7 +1060,7 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::item) ccx.tcx.tcache.insert(local_def(it.id), tpt); return tpt; } - ast::item_ty(t, ref generics) => { + ast::item_ty(ref t, ref generics) => { match tcx.tcache.find(&local_def(it.id)) { Some(&tpt) => return tpt, None => { } @@ -1124,7 +1124,7 @@ pub fn ty_of_foreign_item(ccx: &CrateCtxt, generics, abis) } - ast::foreign_item_static(t, _) => { + ast::foreign_item_static(ref t, _) => { ty::ty_param_bounds_and_ty { generics: ty::Generics { type_param_defs: @~[], @@ -1215,8 +1215,8 @@ pub fn ty_of_foreign_fn_decl(ccx: &CrateCtxt, let ty_generics = ty_generics(ccx, None, ast_generics, 0); let region_param_names = RegionParamNames::from_generics(ast_generics); let rb = in_binding_rscope(&empty_rscope, region_param_names); - let input_tys = decl.inputs.map(|a| ty_of_arg(ccx, &rb, *a, None) ); - let output_ty = ast_ty_to_ty(ccx, &rb, decl.output); + let input_tys = decl.inputs.map(|a| ty_of_arg(ccx, &rb, a, None) ); + let output_ty = ast_ty_to_ty(ccx, &rb, &decl.output); let t_fn = ty::mk_bare_fn( ccx.tcx, diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index d0c8ff03e388..8c37c1510cf2 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -110,7 +110,7 @@ pub struct Path { global: bool, idents: ~[ident], rp: Option, - types: ~[@Ty], + types: ~[Ty], } pub type crate_num = int; @@ -361,7 +361,7 @@ pub enum stmt_ { #[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct local_ { is_mutbl: bool, - ty: @Ty, + ty: Ty, pat: @pat, init: Option<@expr>, id: node_id, @@ -429,12 +429,12 @@ pub enum expr_ { expr_vstore(@expr, expr_vstore), expr_vec(~[@expr], mutability), expr_call(@expr, ~[@expr], CallSugar), - expr_method_call(node_id, @expr, ident, ~[@Ty], ~[@expr], CallSugar), + expr_method_call(node_id, @expr, ident, ~[Ty], ~[@expr], CallSugar), expr_tup(~[@expr]), expr_binary(node_id, binop, @expr, @expr), expr_unary(node_id, unop, @expr), expr_lit(@lit), - expr_cast(@expr, @Ty), + expr_cast(@expr, Ty), expr_if(@expr, blk, Option<@expr>), expr_while(@expr, blk), /* Conditionless loop (can be exited with break, cont, or ret) @@ -454,7 +454,7 @@ pub enum expr_ { expr_copy(@expr), expr_assign(@expr, @expr), expr_assign_op(node_id, binop, @expr, @expr), - expr_field(@expr, ident, ~[@Ty]), + expr_field(@expr, ident, ~[Ty]), expr_index(node_id, @expr, @expr), expr_path(Path), @@ -604,7 +604,7 @@ pub enum lit_ { // type structure in middle/ty.rs as well. #[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct mt { - ty: @Ty, + ty: ~Ty, mutbl: mutability, } @@ -733,7 +733,7 @@ pub enum ty_ { ty_rptr(Option, mt), ty_closure(@TyClosure), ty_bare_fn(@TyBareFn), - ty_tup(~[@Ty]), + ty_tup(~[Ty]), ty_path(Path, Option>, node_id), // for #7264; see above ty_mac(mac), // ty_infer means the type should be inferred instead of it having been @@ -762,7 +762,7 @@ pub struct inline_asm { #[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct arg { is_mutbl: bool, - ty: @Ty, + ty: Ty, pat: @pat, id: node_id, } @@ -770,7 +770,7 @@ pub struct arg { #[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct fn_decl { inputs: ~[arg], - output: @Ty, + output: Ty, cf: ret_style, } @@ -845,7 +845,7 @@ pub struct foreign_mod { #[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct variant_arg { - ty: @Ty, + ty: Ty, id: node_id, } @@ -959,7 +959,7 @@ impl visibility { pub struct struct_field_ { kind: struct_field_kind, id: node_id, - ty: @Ty, + ty: Ty, attrs: ~[attribute], } @@ -995,17 +995,17 @@ pub struct item { #[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum item_ { - item_static(@Ty, mutability, @expr), + item_static(Ty, mutability, @expr), item_fn(fn_decl, purity, AbiSet, Generics, blk), item_mod(_mod), item_foreign_mod(foreign_mod), - item_ty(@Ty, Generics), + item_ty(Ty, Generics), item_enum(enum_def, Generics), item_struct(@struct_def, Generics), item_trait(Generics, ~[trait_ref], ~[trait_method]), item_impl(Generics, Option, // (optional) trait this impl implements - @Ty, // self + Ty, // self ~[@method]), // a macro invocation (which includes macro definition) item_mac(mac), @@ -1024,7 +1024,7 @@ pub struct foreign_item { #[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum foreign_item_ { foreign_item_fn(fn_decl, purity, Generics), - foreign_item_static(@Ty, /* is_mutbl */ bool), + foreign_item_static(Ty, /* is_mutbl */ bool), } // The data we save and restore about an inlined item or method. This is not diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 0388115d7ef9..73220ec28817 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -39,31 +39,30 @@ pub trait AstBuilder { global: bool, idents: ~[ast::ident], rp: Option, - types: ~[@ast::Ty]) + types: ~[ast::Ty]) -> ast::Path; // types - fn ty_mt(&self, ty: @ast::Ty, mutbl: ast::mutability) -> ast::mt; + fn ty_mt(&self, ty: ast::Ty, mutbl: ast::mutability) -> ast::mt; - fn ty(&self, span: span, ty: ast::ty_) -> @ast::Ty; - fn ty_path(&self, ast::Path, Option>) -> @ast::Ty; - fn ty_ident(&self, span: span, idents: ast::ident) -> @ast::Ty; + fn ty(&self, span: span, ty: ast::ty_) -> ast::Ty; + fn ty_path(&self, ast::Path, Option>) -> ast::Ty; + fn ty_ident(&self, span: span, idents: ast::ident) -> ast::Ty; fn ty_rptr(&self, span: span, - ty: @ast::Ty, + ty: ast::Ty, lifetime: Option, - mutbl: ast::mutability) - -> @ast::Ty; - fn ty_uniq(&self, span: span, ty: @ast::Ty) -> @ast::Ty; - fn ty_box(&self, span: span, ty: @ast::Ty, mutbl: ast::mutability) -> @ast::Ty; + mutbl: ast::mutability) -> ast::Ty; + fn ty_uniq(&self, span: span, ty: ast::Ty) -> ast::Ty; + fn ty_box(&self, span: span, ty: ast::Ty, mutbl: ast::mutability) -> ast::Ty; - fn ty_option(&self, ty: @ast::Ty) -> @ast::Ty; - fn ty_infer(&self, sp: span) -> @ast::Ty; - fn ty_nil(&self) -> @ast::Ty; + fn ty_option(&self, ty: ast::Ty) -> ast::Ty; + fn ty_infer(&self, sp: span) -> ast::Ty; + fn ty_nil(&self) -> ast::Ty; - fn ty_vars(&self, ty_params: &OptVec) -> ~[@ast::Ty]; - fn ty_vars_global(&self, ty_params: &OptVec) -> ~[@ast::Ty]; - fn ty_field_imm(&self, span: span, name: ident, ty: @ast::Ty) -> ast::ty_field; + fn ty_vars(&self, ty_params: &OptVec) -> ~[ast::Ty]; + fn ty_vars_global(&self, ty_params: &OptVec) -> ~[ast::Ty]; + fn ty_field_imm(&self, span: span, name: ident, ty: ast::Ty) -> ast::ty_field; fn strip_bounds(&self, bounds: &Generics) -> Generics; fn typaram(&self, id: ast::ident, bounds: OptVec) -> ast::TyParam; @@ -167,25 +166,25 @@ pub trait AstBuilder { fn item(&self, span: span, name: ident, attrs: ~[ast::attribute], node: ast::item_) -> @ast::item; - fn arg(&self, span: span, name: ident, ty: @ast::Ty) -> ast::arg; + fn arg(&self, span: span, name: ident, ty: ast::Ty) -> ast::arg; // XXX unused self - fn fn_decl(&self, inputs: ~[ast::arg], output: @ast::Ty) -> ast::fn_decl; + fn fn_decl(&self, inputs: ~[ast::arg], output: ast::Ty) -> ast::fn_decl; fn item_fn_poly(&self, span: span, name: ident, inputs: ~[ast::arg], - output: @ast::Ty, + output: ast::Ty, generics: Generics, body: ast::blk) -> @ast::item; fn item_fn(&self, span: span, name: ident, inputs: ~[ast::arg], - output: @ast::Ty, + output: ast::Ty, body: ast::blk) -> @ast::item; - fn variant(&self, span: span, name: ident, tys: ~[@ast::Ty]) -> ast::variant; + fn variant(&self, span: span, name: ident, tys: ~[ast::Ty]) -> ast::variant; fn item_enum_poly(&self, span: span, name: ident, @@ -207,9 +206,9 @@ pub trait AstBuilder { fn item_ty_poly(&self, span: span, name: ident, - ty: @ast::Ty, + ty: ast::Ty, generics: Generics) -> @ast::item; - fn item_ty(&self, span: span, name: ident, ty: @ast::Ty) -> @ast::item; + fn item_ty(&self, span: span, name: ident, ty: ast::Ty) -> @ast::item; fn attribute(&self, sp: span, mi: @ast::meta_item) -> ast::attribute; @@ -239,7 +238,7 @@ impl AstBuilder for @ExtCtxt { global: bool, idents: ~[ast::ident], rp: Option, - types: ~[@ast::Ty]) + types: ~[ast::Ty]) -> ast::Path { ast::Path { span: sp, @@ -250,15 +249,15 @@ impl AstBuilder for @ExtCtxt { } } - fn ty_mt(&self, ty: @ast::Ty, mutbl: ast::mutability) -> ast::mt { + fn ty_mt(&self, ty: ast::Ty, mutbl: ast::mutability) -> ast::mt { ast::mt { - ty: ty, + ty: ~ty, mutbl: mutbl } } - fn ty(&self, span: span, ty: ast::ty_) -> @ast::Ty { - @ast::Ty { + fn ty(&self, span: span, ty: ast::ty_) -> ast::Ty { + ast::Ty { id: self.next_id(), span: span, node: ty @@ -266,7 +265,7 @@ impl AstBuilder for @ExtCtxt { } fn ty_path(&self, path: ast::Path, bounds: Option>) - -> @ast::Ty { + -> ast::Ty { self.ty(path.span, ast::ty_path(path, bounds, self.next_id())) } @@ -274,28 +273,28 @@ impl AstBuilder for @ExtCtxt { // Might need to take bounds as an argument in the future, if you ever want // to generate a bounded existential trait type. fn ty_ident(&self, span: span, ident: ast::ident) - -> @ast::Ty { + -> ast::Ty { self.ty_path(self.path_ident(span, ident), None) } fn ty_rptr(&self, span: span, - ty: @ast::Ty, + ty: ast::Ty, lifetime: Option, mutbl: ast::mutability) - -> @ast::Ty { + -> ast::Ty { self.ty(span, ast::ty_rptr(lifetime, self.ty_mt(ty, mutbl))) } - fn ty_uniq(&self, span: span, ty: @ast::Ty) -> @ast::Ty { + fn ty_uniq(&self, span: span, ty: ast::Ty) -> ast::Ty { self.ty(span, ast::ty_uniq(self.ty_mt(ty, ast::m_imm))) } fn ty_box(&self, span: span, - ty: @ast::Ty, mutbl: ast::mutability) -> @ast::Ty { + ty: ast::Ty, mutbl: ast::mutability) -> ast::Ty { self.ty(span, ast::ty_box(self.ty_mt(ty, mutbl))) } - fn ty_option(&self, ty: @ast::Ty) -> @ast::Ty { + fn ty_option(&self, ty: ast::Ty) -> ast::Ty { self.ty_path( self.path_all(dummy_sp(), true, @@ -308,20 +307,20 @@ impl AstBuilder for @ExtCtxt { ~[ ty ]), None) } - fn ty_field_imm(&self, span: span, name: ident, ty: @ast::Ty) -> ast::ty_field { + fn ty_field_imm(&self, span: span, name: ident, ty: ast::Ty) -> ast::ty_field { respan(span, ast::ty_field_ { ident: name, - mt: ast::mt { ty: ty, mutbl: ast::m_imm }, + mt: ast::mt { ty: ~ty, mutbl: ast::m_imm }, }) } - fn ty_infer(&self, span: span) -> @ast::Ty { + fn ty_infer(&self, span: span) -> ast::Ty { self.ty(span, ast::ty_infer) } - fn ty_nil(&self) -> @ast::Ty { - @ast::Ty { + fn ty_nil(&self) -> ast::Ty { + ast::Ty { id: self.next_id(), node: ast::ty_nil, span: dummy_sp(), @@ -335,12 +334,12 @@ impl AstBuilder for @ExtCtxt { // 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: &OptVec) -> ~[@ast::Ty] { + fn ty_vars(&self, ty_params: &OptVec) -> ~[ast::Ty] { opt_vec::take_vec( ty_params.map(|p| self.ty_ident(dummy_sp(), p.ident))) } - fn ty_vars_global(&self, ty_params: &OptVec) -> ~[@ast::Ty] { + fn ty_vars_global(&self, ty_params: &OptVec) -> ~[ast::Ty] { opt_vec::take_vec( ty_params.map(|p| self.ty_path( self.path_global(dummy_sp(), ~[p.ident]), None))) @@ -642,7 +641,7 @@ impl AstBuilder for @ExtCtxt { self.lambda1(span, self.blk(span, stmts, None), ident) } - fn arg(&self, span: span, ident: ast::ident, ty: @ast::Ty) -> ast::arg { + fn arg(&self, span: span, ident: ast::ident, ty: ast::Ty) -> ast::arg { let arg_pat = self.pat_ident(span, ident); ast::arg { is_mutbl: false, @@ -653,7 +652,7 @@ impl AstBuilder for @ExtCtxt { } // XXX unused self - fn fn_decl(&self, inputs: ~[ast::arg], output: @ast::Ty) -> ast::fn_decl { + fn fn_decl(&self, inputs: ~[ast::arg], output: ast::Ty) -> ast::fn_decl { ast::fn_decl { inputs: inputs, output: output, @@ -677,7 +676,7 @@ impl AstBuilder for @ExtCtxt { span: span, name: ident, inputs: ~[ast::arg], - output: @ast::Ty, + output: ast::Ty, generics: Generics, body: ast::blk) -> @ast::item { self.item(span, @@ -694,7 +693,7 @@ impl AstBuilder for @ExtCtxt { span: span, name: ident, inputs: ~[ast::arg], - output: @ast::Ty, + output: ast::Ty, body: ast::blk ) -> @ast::item { self.item_fn_poly( @@ -706,10 +705,10 @@ impl AstBuilder for @ExtCtxt { body) } - fn variant(&self, span: span, name: ident, tys: ~[@ast::Ty]) -> ast::variant { - let args = do tys.map |ty| { - ast::variant_arg { ty: *ty, id: self.next_id() } - }; + fn variant(&self, span: span, name: ident, tys: ~[ast::Ty]) -> ast::variant { + let args = tys.consume_iter().transform(|ty| { + ast::variant_arg { ty: ty, id: self.next_id() } + }).collect(); respan(span, ast::variant_ { @@ -773,12 +772,12 @@ impl AstBuilder for @ExtCtxt { ) } - fn item_ty_poly(&self, span: span, name: ident, ty: @ast::Ty, + fn item_ty_poly(&self, span: span, name: ident, ty: ast::Ty, generics: Generics) -> @ast::item { self.item(span, name, ~[], ast::item_ty(ty, generics)) } - fn item_ty(&self, span: span, name: ident, ty: @ast::Ty) -> @ast::item { + fn item_ty(&self, span: span, name: ident, ty: ast::Ty) -> @ast::item { self.item_ty_poly(span, name, ty, ast_util::empty_generics()) } diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index 10282cb6f0ae..01769482d082 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -456,7 +456,7 @@ impl<'self> MethodDef<'self> { } fn get_ret_ty(&self, cx: @ExtCtxt, span: span, - generics: &Generics, type_ident: ident) -> @ast::Ty { + generics: &Generics, type_ident: ident) -> ast::Ty { self.ret_ty.to_ty(cx, span, type_ident, generics) } @@ -466,7 +466,7 @@ impl<'self> MethodDef<'self> { fn split_self_nonself_args(&self, cx: @ExtCtxt, span: span, type_ident: ident, generics: &Generics) - -> (ast::explicit_self, ~[@expr], ~[@expr], ~[(ident, @ast::Ty)]) { + -> (ast::explicit_self, ~[@expr], ~[@expr], ~[(ident, ast::Ty)]) { let mut self_args = ~[]; let mut nonself_args = ~[]; @@ -514,7 +514,7 @@ impl<'self> MethodDef<'self> { type_ident: ident, generics: &Generics, explicit_self: ast::explicit_self, - arg_types: ~[(ident, @ast::Ty)], + arg_types: ~[(ident, ast::Ty)], body: @expr) -> @ast::method { // create the generics that aren't for Self let fn_generics = self.generics.to_generics(cx, span, type_ident, generics); diff --git a/src/libsyntax/ext/deriving/ty.rs b/src/libsyntax/ext/deriving/ty.rs index c820371714bf..255bc6c98775 100644 --- a/src/libsyntax/ext/deriving/ty.rs +++ b/src/libsyntax/ext/deriving/ty.rs @@ -61,7 +61,7 @@ impl<'self> Path<'self> { span: span, self_ty: ident, self_generics: &Generics) - -> @ast::Ty { + -> ast::Ty { cx.ty_path(self.to_path(cx, span, self_ty, self_generics), None) } pub fn to_path(&self, @@ -122,7 +122,7 @@ impl<'self> Ty<'self> { span: span, self_ty: ident, self_generics: &Generics) - -> @ast::Ty { + -> ast::Ty { match *self { Ptr(ref ty, ref ptr) => { let raw_ty = ty.to_ty(cx, span, self_ty, self_generics); diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs index 58838b0c40bd..a4873e6e34b4 100644 --- a/src/libsyntax/ext/pipes/ast_builder.rs +++ b/src/libsyntax/ext/pipes/ast_builder.rs @@ -42,19 +42,19 @@ pub fn path_global(ids: ~[ident], span: span) -> ast::Path { } pub trait append_types { - fn add_ty(&self, ty: @ast::Ty) -> ast::Path; - fn add_tys(&self, tys: ~[@ast::Ty]) -> ast::Path; + fn add_ty(&self, ty: ast::Ty) -> ast::Path; + fn add_tys(&self, tys: ~[ast::Ty]) -> ast::Path; } impl append_types for ast::Path { - fn add_ty(&self, ty: @ast::Ty) -> ast::Path { + fn add_ty(&self, ty: ast::Ty) -> ast::Path { ast::Path { types: vec::append_one(copy self.types, ty), .. copy *self } } - fn add_tys(&self, tys: ~[@ast::Ty]) -> ast::Path { + fn add_tys(&self, tys: ~[ast::Ty]) -> ast::Path { ast::Path { types: vec::append(copy self.types, tys), .. copy *self diff --git a/src/libsyntax/ext/pipes/check.rs b/src/libsyntax/ext/pipes/check.rs index 8c2898737a35..adf10215cb56 100644 --- a/src/libsyntax/ext/pipes/check.rs +++ b/src/libsyntax/ext/pipes/check.rs @@ -49,7 +49,7 @@ impl proto::visitor<(), (), ()> for @ExtCtxt { } } - fn visit_message(&self, name: @str, _span: span, _tys: &[@ast::Ty], + fn visit_message(&self, name: @str, _span: span, _tys: &[ast::Ty], this: state, next: Option) { match next { Some(ref next_state) => { diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index 57174f216fe5..98fc9aa61784 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -25,7 +25,7 @@ use std::vec; pub trait gen_send { fn gen_send(&mut self, cx: @ExtCtxt, try: bool) -> @ast::item; - fn to_ty(&mut self, cx: @ExtCtxt) -> @ast::Ty; + fn to_ty(&mut self, cx: @ExtCtxt) -> ast::Ty; } pub trait to_type_decls { @@ -37,7 +37,7 @@ pub trait to_type_decls { pub trait gen_init { fn gen_init(&self, cx: @ExtCtxt) -> @ast::item; fn compile(&self, cx: @ExtCtxt) -> @ast::item; - fn buffer_ty_path(&self, cx: @ExtCtxt) -> @ast::Ty; + fn buffer_ty_path(&self, cx: @ExtCtxt) -> ast::Ty; fn gen_buffer_type(&self, cx: @ExtCtxt) -> @ast::item; fn gen_buffer_init(&self, ext_cx: @ExtCtxt) -> @ast::expr; fn gen_init_bounded(&self, ext_cx: @ExtCtxt) -> @ast::expr; @@ -56,7 +56,7 @@ impl gen_send for message { next.generics.ty_params.len()); let arg_names = vec::from_fn(tys.len(), |i| cx.ident_of("x_"+i.to_str())); let args_ast: ~[ast::arg] = arg_names.iter().zip(tys.iter()) - .transform(|(n, t)| cx.arg(span, *n, *t)).collect(); + .transform(|(n, t)| cx.arg(span, copy *n, copy *t)).collect(); let pipe_ty = cx.ty_path( path(~[this.data_name()], span) @@ -137,7 +137,7 @@ impl gen_send for message { let arg_names = vec::from_fn(tys.len(), |i| "x_" + i.to_str()); let args_ast: ~[ast::arg] = arg_names.iter().zip(tys.iter()) - .transform(|(n, t)| cx.arg(span, cx.ident_of(*n), *t)).collect(); + .transform(|(&n, t)| cx.arg(span, cx.ident_of(n), copy *t)).collect(); let args_ast = vec::append( ~[cx.arg(span, @@ -189,7 +189,7 @@ impl gen_send for message { } } - fn to_ty(&mut self, cx: @ExtCtxt) -> @ast::Ty { + fn to_ty(&mut self, cx: @ExtCtxt) -> ast::Ty { cx.ty_path(path(~[cx.ident_of(self.name())], self.span()) .add_tys(cx.ty_vars(&self.get_generics().ty_params)), None) } @@ -369,7 +369,7 @@ impl gen_init for protocol { }) } - fn buffer_ty_path(&self, cx: @ExtCtxt) -> @ast::Ty { + fn buffer_ty_path(&self, cx: @ExtCtxt) -> ast::Ty { let mut params: OptVec = opt_vec::Empty; for self.states.iter().advance |s| { for s.generics.ty_params.iter().advance |tp| { diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs index f3d7158de526..2fe8456c2749 100644 --- a/src/libsyntax/ext/pipes/proto.rs +++ b/src/libsyntax/ext/pipes/proto.rs @@ -37,11 +37,11 @@ impl direction { pub struct next_state { state: @str, - tys: ~[@ast::Ty], + tys: ~[ast::Ty], } // name, span, data, current state, next state -pub struct message(@str, span, ~[@ast::Ty], state, Option); +pub struct message(@str, span, ~[ast::Ty], state, Option); impl message { pub fn name(&mut self) -> @str { @@ -81,7 +81,7 @@ impl state_ { pub fn add_message(@self, name: @str, span: span, - data: ~[@ast::Ty], + data: ~[ast::Ty], next: Option) { self.messages.push(message(name, span, data, self, next)); @@ -96,7 +96,7 @@ impl state_ { } /// Returns the type that is used for the messages. - pub fn to_ty(&self, cx: @ExtCtxt) -> @ast::Ty { + pub fn to_ty(&self, cx: @ExtCtxt) -> ast::Ty { cx.ty_path (path(~[cx.ident_of(self.name)],self.span).add_tys( cx.ty_vars(&self.generics.ty_params)), None) @@ -206,7 +206,7 @@ impl protocol_ { pub trait visitor { fn visit_proto(&self, proto: protocol, st: &[Tstate]) -> Tproto; fn visit_state(&self, state: state, m: &[Tmessage]) -> Tstate; - fn visit_message(&self, name: @str, spane: span, tys: &[@ast::Ty], + fn visit_message(&self, name: @str, spane: span, tys: &[ast::Ty], this: state, next: Option) -> Tmessage; } diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index db1902753a38..c550e3382a23 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -88,13 +88,13 @@ pub mod rt { } } - impl ToSource for @ast::Ty { + impl ToSource for ast::Ty { fn to_source(&self) -> @str { - pprust::ty_to_str(*self, get_ident_interner()).to_managed() + pprust::ty_to_str(self, get_ident_interner()).to_managed() } } - impl<'self> ToSource for &'self [@ast::Ty] { + impl<'self> ToSource for &'self [ast::Ty] { fn to_source(&self) -> @str { self.map(|i| i.to_source()).connect(", ").to_managed() } @@ -216,13 +216,13 @@ pub mod rt { } } - impl ToTokens for @ast::Ty { + impl ToTokens for ast::Ty { fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] { cx.parse_tts(self.to_source()) } } - impl<'self> ToTokens for &'self [@ast::Ty] { + impl<'self> ToTokens for &'self [ast::Ty] { fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] { cx.parse_tts(self.to_source()) } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index c6592d36e409..e2beebcead26 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -28,7 +28,7 @@ pub trait ast_fold { fn fold_pat(@self, @pat) -> @pat; fn fold_decl(@self, @decl) -> Option<@decl>; fn fold_expr(@self, @expr) -> @expr; - fn fold_ty(@self, @Ty) -> @Ty; + fn fold_ty(@self, &Ty) -> Ty; fn fold_mod(@self, &_mod) -> _mod; fn fold_foreign_mod(@self, &foreign_mod) -> foreign_mod; fn fold_variant(@self, &variant) -> variant; @@ -107,7 +107,7 @@ fn fold_attribute_(at: attribute, fld: @ast_fold) -> attribute { fn fold_arg_(a: arg, fld: @ast_fold) -> arg { ast::arg { is_mutbl: a.is_mutbl, - ty: fld.fold_ty(a.ty), + ty: fld.fold_ty(&a.ty), pat: fld.fold_pat(a.pat), id: fld.new_id(a.id), } @@ -154,8 +154,8 @@ fn maybe_fold_ident(t : &token::Token, fld: @ast_fold) -> token::Token { pub fn fold_fn_decl(decl: &ast::fn_decl, fld: @ast_fold) -> ast::fn_decl { ast::fn_decl { - inputs: decl.inputs.map(|x| fold_arg_(*x, fld)), - output: fld.fold_ty(decl.output), + inputs: decl.inputs.map(|x| fold_arg_(/*bad*/ copy *x, fld)), + output: fld.fold_ty(&decl.output), cf: decl.cf, } } @@ -226,14 +226,14 @@ fn noop_fold_foreign_item(ni: @foreign_item, fld: @ast_fold) foreign_item_fn(ref fdec, purity, ref generics) => { foreign_item_fn( ast::fn_decl { - inputs: fdec.inputs.map(|a| fold_arg(*a)), - output: fld.fold_ty(fdec.output), + inputs: fdec.inputs.map(|a| fold_arg(/*bad*/copy *a)), + output: fld.fold_ty(&fdec.output), cf: fdec.cf, }, purity, fold_generics(generics, fld)) } - foreign_item_static(t, m) => { + foreign_item_static(ref t, m) => { foreign_item_static(fld.fold_ty(t), m) } }, @@ -260,14 +260,14 @@ fn noop_fold_struct_field(sf: @struct_field, fld: @ast_fold) @spanned { node: ast::struct_field_ { kind: copy sf.node.kind, id: sf.node.id, - ty: fld.fold_ty(sf.node.ty), + ty: fld.fold_ty(&sf.node.ty), attrs: sf.node.attrs.map(|e| fold_attribute(*e)) }, span: sf.span } } pub fn noop_fold_item_underscore(i: &item_, fld: @ast_fold) -> item_ { match *i { - item_static(t, m, e) => item_static(fld.fold_ty(t), m, fld.fold_expr(e)), + item_static(ref t, m, e) => item_static(fld.fold_ty(t), m, fld.fold_expr(e)), item_fn(ref decl, purity, abi, ref generics, ref body) => { item_fn( fold_fn_decl(decl, fld), @@ -281,7 +281,7 @@ pub fn noop_fold_item_underscore(i: &item_, fld: @ast_fold) -> item_ { item_foreign_mod(ref nm) => { item_foreign_mod(fld.fold_foreign_mod(nm)) } - item_ty(t, ref generics) => { + item_ty(ref t, ref generics) => { item_ty(fld.fold_ty(t), fold_generics(generics, fld)) } item_enum(ref enum_definition, ref generics) => { @@ -297,7 +297,7 @@ pub fn noop_fold_item_underscore(i: &item_, fld: @ast_fold) -> item_ { let struct_def = fold_struct_def(*struct_def, fld); item_struct(struct_def, /* FIXME (#2543) */ copy *generics) } - item_impl(ref generics, ref ifce, ty, ref methods) => { + item_impl(ref generics, ref ifce, ref ty, ref methods) => { item_impl( fold_generics(generics, fld), ifce.map(|p| fold_trait_ref(p, fld)), @@ -348,7 +348,7 @@ fn fold_struct_field(f: @struct_field, fld: @ast_fold) -> @struct_field { node: ast::struct_field_ { kind: copy f.node.kind, id: fld.new_id(f.node.id), - ty: fld.fold_ty(f.node.ty), + ty: fld.fold_ty(&f.node.ty), attrs: /* FIXME (#2543) */ copy f.node.attrs, }, span: fld.new_span(f.span), @@ -518,7 +518,7 @@ pub fn noop_fold_expr(e: &expr_, fld: @ast_fold) -> expr_ { fld.new_id(callee_id), fld.fold_expr(f), fld.fold_ident(i), - tps.map(|x| fld.fold_ty(*x)), + tps.map(|x| fld.fold_ty(x)), fld.map_exprs(|x| fld.fold_expr(x), *args), blk ) @@ -541,7 +541,7 @@ pub fn noop_fold_expr(e: &expr_, fld: @ast_fold) -> expr_ { expr_loop_body(f) => expr_loop_body(fld.fold_expr(f)), expr_do_body(f) => expr_do_body(fld.fold_expr(f)), expr_lit(_) => copy *e, - expr_cast(expr, ty) => expr_cast(fld.fold_expr(expr), ty), + expr_cast(expr, ref ty) => expr_cast(fld.fold_expr(expr), copy *ty), expr_addr_of(m, ohs) => expr_addr_of(m, fld.fold_expr(ohs)), expr_if(cond, ref tr, fl) => { expr_if( @@ -587,7 +587,7 @@ pub fn noop_fold_expr(e: &expr_, fld: @ast_fold) -> expr_ { expr_field(el, id, ref tys) => { expr_field( fld.fold_expr(el), fld.fold_ident(id), - tys.map(|x| fld.fold_ty(*x)) + tys.map(|x| fld.fold_ty(x)) ) } expr_index(callee_id, el, er) => { @@ -637,7 +637,7 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ { let fold_mac = |x| fold_mac_(x, fld); fn fold_mt(mt: &mt, fld: @ast_fold) -> mt { mt { - ty: fld.fold_ty(mt.ty), + ty: ~fld.fold_ty(mt.ty), mutbl: mt.mutbl, } } @@ -682,7 +682,7 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ { decl: fold_fn_decl(&f.decl, fld) }) } - ty_tup(ref tys) => ty_tup(tys.map(|ty| fld.fold_ty(*ty))), + ty_tup(ref tys) => ty_tup(tys.map(|ty| fld.fold_ty(ty))), ty_path(ref path, ref bounds, id) => ty_path(fld.fold_path(path), fold_opt_bounds(bounds, fld), fld.new_id(id)), ty_fixed_length_vec(ref mt, e) => { @@ -714,7 +714,7 @@ fn noop_fold_foreign_mod(nm: &foreign_mod, fld: @ast_fold) -> foreign_mod { fn noop_fold_variant(v: &variant_, fld: @ast_fold) -> variant_ { fn fold_variant_arg_(va: variant_arg, fld: @ast_fold) -> variant_arg { - ast::variant_arg { ty: fld.fold_ty(va.ty), id: fld.new_id(va.id) } + ast::variant_arg { ty: fld.fold_ty(&va.ty), id: fld.new_id(va.id) } } let fold_variant_arg = |x| fold_variant_arg_(x, fld); @@ -722,7 +722,7 @@ fn noop_fold_variant(v: &variant_, fld: @ast_fold) -> variant_ { match v.kind { tuple_variant_kind(ref variant_args) => { kind = tuple_variant_kind(do variant_args.map |x| { - fold_variant_arg(*x) + fold_variant_arg(/*bad*/ copy *x) }) } struct_variant_kind(struct_def) => { @@ -761,14 +761,14 @@ fn noop_fold_path(p: &Path, fld: @ast_fold) -> Path { global: p.global, idents: p.idents.map(|x| fld.fold_ident(*x)), rp: p.rp, - types: p.types.map(|x| fld.fold_ty(*x)), + types: p.types.map(|x| fld.fold_ty(x)), } } fn noop_fold_local(l: &local_, fld: @ast_fold) -> local_ { local_ { is_mutbl: l.is_mutbl, - ty: fld.fold_ty(l.ty), + ty: fld.fold_ty(&l.ty), pat: fld.fold_pat(l.pat), init: l.init.map(|e| fld.fold_expr(*e)), id: fld.new_id(l.id), @@ -838,7 +838,7 @@ impl ast_fold for AstFoldFns { node: ast::struct_field_ { kind: copy sf.node.kind, id: sf.node.id, - ty: (self as @ast_fold).fold_ty(sf.node.ty), + ty: self.fold_ty(&sf.node.ty), attrs: copy sf.node.attrs, }, span: (self.new_span)(sf.span), @@ -887,9 +887,9 @@ impl ast_fold for AstFoldFns { span: (self.new_span)(s), } } - fn fold_ty(@self, x: @Ty) -> @Ty { + fn fold_ty(@self, x: &Ty) -> Ty { let (n, s) = (self.fold_ty)(&x.node, x.span, self as @ast_fold); - @Ty { + Ty { id: (self.new_id)(x.id), node: n, span: (self.new_span)(s), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 4c662cc46213..d18d24c2b90e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -824,7 +824,7 @@ impl Parser { // parse a possibly mutable type pub fn parse_mt(&self) -> mt { let mutbl = self.parse_mutability(); - let t = self.parse_ty(false); + let t = ~self.parse_ty(false); mt { ty: t, mutbl: mutbl } } @@ -835,7 +835,7 @@ impl Parser { let mutbl = self.parse_mutability(); let id = self.parse_ident(); self.expect(&token::COLON); - let ty = self.parse_ty(false); + let ty = ~self.parse_ty(false); spanned( lo, ty.span.hi, @@ -847,13 +847,13 @@ impl Parser { } // parse optional return type [ -> TY ] in function decl - pub fn parse_ret_ty(&self) -> (ret_style, @Ty) { + pub fn parse_ret_ty(&self) -> (ret_style, Ty) { return if self.eat(&token::RARROW) { let lo = self.span.lo; if self.eat(&token::NOT) { ( noreturn, - @Ty { + Ty { id: self.get_id(), node: ty_bot, span: mk_sp(lo, self.last_span.hi) @@ -866,7 +866,7 @@ impl Parser { let pos = self.span.lo; ( return_val, - @Ty { + Ty { id: self.get_id(), node: ty_nil, span: mk_sp(pos, pos), @@ -878,7 +878,7 @@ impl Parser { // parse a type. // Useless second parameter for compatibility with quasiquote macros. // Bleh! - pub fn parse_ty(&self, _: bool) -> @Ty { + pub fn parse_ty(&self, _: bool) -> Ty { maybe_whole!(self, nt_ty); let lo = self.span.lo; @@ -975,7 +975,7 @@ impl Parser { }; let sp = mk_sp(lo, self.last_span.hi); - @Ty {id: self.get_id(), node: t, span: sp} + Ty {id: self.get_id(), node: t, span: sp} } // parse the type following a @ or a ~ @@ -1116,7 +1116,7 @@ impl Parser { let t = if self.eat(&token::COLON) { self.parse_ty(false) } else { - @Ty { + Ty { id: self.get_id(), node: ty_infer, span: mk_sp(self.span.lo, self.span.hi), @@ -1463,7 +1463,7 @@ impl Parser { pub fn mk_method_call(&self, rcvr: @expr, ident: ident, - tps: ~[@Ty], + tps: ~[Ty], args: ~[@expr], sugar: CallSugar) -> ast::expr_ { expr_method_call(self.get_id(), rcvr, ident, tps, args, sugar) @@ -1473,7 +1473,7 @@ impl Parser { expr_index(self.get_id(), expr, idx) } - pub fn mk_field(&self, expr: @expr, ident: ident, tys: ~[@Ty]) -> ast::expr_ { + pub fn mk_field(&self, expr: @expr, ident: ident, tys: ~[Ty]) -> ast::expr_ { expr_field(expr, ident, tys) } @@ -2215,7 +2215,7 @@ impl Parser { // No argument list - `do foo {` ast::fn_decl { inputs: ~[], - output: @Ty { + output: Ty { id: self.get_id(), node: ty_infer, span: *self.span @@ -2826,7 +2826,7 @@ impl Parser { self.obsolete(*self.span, ObsoleteMutWithMultipleBindings) } - let mut ty = @Ty { + let mut ty = Ty { id: self.get_id(), node: ty_infer, span: mk_sp(lo, lo), @@ -3235,7 +3235,7 @@ impl Parser { // parse a generic use site fn parse_generic_values( - &self) -> (OptVec, ~[@Ty]) + &self) -> (OptVec, ~[Ty]) { if !self.eat(&token::LT) { (opt_vec::Empty, ~[]) @@ -3245,7 +3245,7 @@ impl Parser { } fn parse_generic_values_after_lt( - &self) -> (OptVec, ~[@Ty]) + &self) -> (OptVec, ~[Ty]) { let lifetimes = self.parse_lifetimes(); let result = self.parse_seq_to_gt( @@ -3455,7 +3455,7 @@ impl Parser { let output = if self.eat(&token::RARROW) { self.parse_ty(false) } else { - @Ty { id: self.get_id(), node: ty_infer, span: *self.span } + Ty { id: self.get_id(), node: ty_infer, span: *self.span } }; ast::fn_decl { @@ -4155,9 +4155,9 @@ impl Parser { seq_sep_trailing_disallowed(token::COMMA), |p| p.parse_ty(false) ); - for arg_tys.iter().advance |ty| { + for arg_tys.consume_iter().advance |ty| { args.push(ast::variant_arg { - ty: *ty, + ty: ty, id: self.get_id(), }); } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 0264903076b9..09d6ecb40fc0 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -104,7 +104,7 @@ pub enum nonterminal { nt_stmt(@ast::stmt), nt_pat( @ast::pat), nt_expr(@ast::expr), - nt_ty( @ast::Ty), + nt_ty( ast::Ty), nt_ident(ast::ident, bool), nt_path( ast::Path), nt_tt( @ast::token_tree), //needs @ed to break a circularity diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index d054f9278945..517065ab1b5c 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -398,7 +398,7 @@ pub fn print_type(s: @ps, ty: &ast::Ty) { } ast::ty_tup(ref elts) => { popen(s); - commasep(s, inconsistent, *elts, |p, &t| print_type(p, t)); + commasep(s, inconsistent, *elts, print_type); if elts.len() == 1 { word(s.s, ","); } @@ -454,7 +454,7 @@ pub fn print_foreign_item(s: @ps, item: &ast::foreign_item) { word(s.s, ";"); end(s); // end the outer fn box } - ast::foreign_item_static(t, m) => { + ast::foreign_item_static(ref t, m) => { head(s, "static"); if m { word_space(s, "mut"); @@ -476,7 +476,7 @@ pub fn print_item(s: @ps, item: &ast::item) { let ann_node = node_item(s, item); (s.ann.pre)(ann_node); match item.node { - ast::item_static(ty, m, expr) => { + ast::item_static(ref ty, m, expr) => { head(s, visibility_qualified(item.vis, "static")); if m == ast::m_mutbl { word_space(s, "mut"); @@ -530,7 +530,7 @@ pub fn print_item(s: @ps, item: &ast::item) { print_foreign_mod(s, nmod, item.attrs); bclose(s, item.span); } - ast::item_ty(ty, ref params) => { + ast::item_ty(ref ty, ref params) => { ibox(s, indent_unit); ibox(s, 0u); word_nbsp(s, visibility_qualified(item.vis, "type")); @@ -559,7 +559,7 @@ pub fn print_item(s: @ps, item: &ast::item) { print_struct(s, struct_def, generics, item.ident, item.span); } - ast::item_impl(ref generics, ref opt_trait, ty, ref methods) => { + ast::item_impl(ref generics, ref opt_trait, ref ty, ref methods) => { head(s, visibility_qualified(item.vis, "impl")); if generics.is_parameterized() { print_generics(s, generics); @@ -694,7 +694,7 @@ pub fn print_struct(s: @ps, ast::named_field(*) => fail!("unexpected named field"), ast::unnamed_field => { maybe_print_comment(s, field.span.lo); - print_type(s, field.node.ty); + print_type(s, &field.node.ty); } } } @@ -718,7 +718,7 @@ pub fn print_struct(s: @ps, print_visibility(s, visibility); print_ident(s, ident); word_nbsp(s, ":"); - print_type(s, field.node.ty); + print_type(s, &field.node.ty); word(s.s, ","); } } @@ -777,7 +777,7 @@ pub fn print_variant(s: @ps, v: &ast::variant) { if !args.is_empty() { popen(s); fn print_variant_arg(s: @ps, arg: &ast::variant_arg) { - print_type(s, arg.ty); + print_type(s, &arg.ty); } commasep(s, consistent, *args, print_variant_arg); pclose(s); @@ -1172,7 +1172,7 @@ pub fn print_expr(s: @ps, expr: &ast::expr) { print_ident(s, ident); if tys.len() > 0u { word(s.s, "::<"); - commasep(s, inconsistent, *tys, |p, &e| print_type(p, e)); + commasep(s, inconsistent, *tys, print_type); word(s.s, ">"); } print_call_post(s, sugar, &blk, &mut base_args); @@ -1198,7 +1198,7 @@ pub fn print_expr(s: @ps, expr: &ast::expr) { print_expr(s, expr); } ast::expr_lit(lit) => print_literal(s, lit), - ast::expr_cast(expr, ty) => { + ast::expr_cast(expr, ref ty) => { print_expr(s, expr); space(s.s); word_space(s, "as"); @@ -1348,7 +1348,7 @@ pub fn print_expr(s: @ps, expr: &ast::expr) { print_ident(s, id); if tys.len() > 0u { word(s.s, "::<"); - commasep(s, inconsistent, *tys, |p, &e| print_type(p, e)); + commasep(s, inconsistent, *tys, print_type); word(s.s, ">"); } } @@ -1437,7 +1437,7 @@ pub fn print_local_decl(s: @ps, loc: &ast::local) { print_irrefutable_pat(s, loc.node.pat); match loc.node.ty.node { ast::ty_infer => (), - _ => { word_space(s, ":"); print_type(s, loc.node.ty); } + _ => { word_space(s, ":"); print_type(s, &loc.node.ty); } } } @@ -1510,7 +1510,7 @@ fn print_path_(s: @ps, path: &ast::Path, colons_before_params: bool, } } - commasep(s, inconsistent, path.types, |p, &e| print_type(p, e)); + commasep(s, inconsistent, path.types, print_type); word(s.s, ">"); } @@ -1693,7 +1693,7 @@ pub fn print_fn_args(s: @ps, decl: &ast::fn_decl, for decl.inputs.iter().advance |arg| { if first { first = false; } else { word_space(s, ","); } - print_arg(s, *arg); + print_arg(s, arg); } end(s); @@ -1711,7 +1711,7 @@ pub fn print_fn_args_and_ret(s: @ps, decl: &ast::fn_decl, _ => { space_if_not_bol(s); word_space(s, "->"); - print_type(s, decl.output); + print_type(s, &decl.output); } } } @@ -1726,7 +1726,7 @@ pub fn print_fn_block_args(s: @ps, decl: &ast::fn_decl) { _ => { space_if_not_bol(s); word_space(s, "->"); - print_type(s, decl.output); + print_type(s, &decl.output); } } @@ -1882,7 +1882,7 @@ pub fn print_mt(s: @ps, mt: &ast::mt) { print_type(s, mt.ty); } -pub fn print_arg(s: @ps, input: ast::arg) { +pub fn print_arg(s: @ps, input: &ast::arg) { ibox(s, indent_unit); if input.is_mutbl { word_space(s, "mut"); @@ -1902,7 +1902,7 @@ pub fn print_arg(s: @ps, input: ast::arg) { space(s.s); } } - print_type(s, input.ty); + print_type(s, &input.ty); } } end(s); @@ -1944,7 +1944,7 @@ pub fn print_ty_fn(s: @ps, } for decl.inputs.iter().advance |arg| { if first { first = false; } else { word_space(s, ","); } - print_arg(s, *arg); + print_arg(s, arg); } end(s); pclose(s); @@ -1958,7 +1958,7 @@ pub fn print_ty_fn(s: @ps, ibox(s, indent_unit); word_space(s, "->"); if decl.cf == ast::noreturn { word_nbsp(s, "!"); } - else { print_type(s, decl.output); } + else { print_type(s, &decl.output); } end(s); } } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index b513b68b74f8..b2d9d49f0ee7 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -83,7 +83,7 @@ pub struct Visitor { visit_decl: @fn(@decl, (E, vt)), visit_expr: @fn(@expr, (E, vt)), visit_expr_post: @fn(@expr, (E, vt)), - visit_ty: @fn(@Ty, (E, vt)), + visit_ty: @fn(&Ty, (E, vt)), visit_generics: @fn(&Generics, (E, vt)), visit_fn: @fn(&fn_kind, &fn_decl, &blk, span, node_id, (E, vt)), visit_ty_method: @fn(&ty_method, (E, vt)), @@ -131,7 +131,7 @@ pub fn visit_view_item(_vi: &view_item, (_e, _v): (E, vt)) { } pub fn visit_local(loc: &local, (e, v): (E, vt)) { (v.visit_pat)(loc.node.pat, (copy e, v)); - (v.visit_ty)(loc.node.ty, (copy e, v)); + (v.visit_ty)(&loc.node.ty, (copy e, v)); match loc.node.init { None => (), Some(ex) => (v.visit_expr)(ex, (e, v)) @@ -144,7 +144,7 @@ fn visit_trait_ref(tref: &ast::trait_ref, (e, v): (E, vt)) { pub fn visit_item(i: &item, (e, v): (E, vt)) { match i.node { - item_static(t, _, ex) => { + item_static(ref t, _, ex) => { (v.visit_ty)(t, (copy e, v)); (v.visit_expr)(ex, (copy e, v)); } @@ -169,7 +169,7 @@ pub fn visit_item(i: &item, (e, v): (E, vt)) { for nm.view_items.iter().advance |vi| { (v.visit_view_item)(vi, (copy e, v)); } for nm.items.iter().advance |ni| { (v.visit_foreign_item)(*ni, (copy e, v)); } } - item_ty(t, ref tps) => { + item_ty(ref t, ref tps) => { (v.visit_ty)(t, (copy e, v)); (v.visit_generics)(tps, (e, v)); } @@ -181,7 +181,7 @@ pub fn visit_item(i: &item, (e, v): (E, vt)) { (e, v) ); } - item_impl(ref tps, ref traits, ty, ref methods) => { + item_impl(ref tps, ref traits, ref ty, ref methods) => { (v.visit_generics)(tps, (copy e, v)); for traits.iter().advance |p| { visit_trait_ref(p, (copy e, v)); @@ -213,7 +213,7 @@ pub fn visit_enum_def(enum_definition: &ast::enum_def, match vr.node.kind { tuple_variant_kind(ref variant_args) => { for variant_args.iter().advance |va| { - (v.visit_ty)(va.ty, (copy e, v)); + (v.visit_ty)(&va.ty, (copy e, v)); } } struct_variant_kind(struct_def) => { @@ -232,25 +232,25 @@ pub fn skip_ty(_t: &Ty, (_e,_v): (E, vt)) {} pub fn visit_ty(t: &Ty, (e, v): (E, vt)) { match t.node { - ty_box(mt) | ty_uniq(mt) | - ty_vec(mt) | ty_ptr(mt) | ty_rptr(_, mt) => { + ty_box(ref mt) | ty_uniq(ref mt) | + ty_vec(ref mt) | ty_ptr(ref mt) | ty_rptr(_, ref mt) => { (v.visit_ty)(mt.ty, (e, v)); }, ty_tup(ref ts) => { for ts.iter().advance |tt| { - (v.visit_ty)(*tt, (copy e, v)); + (v.visit_ty)(tt, (copy e, v)); } }, ty_closure(ref f) => { - for f.decl.inputs.iter().advance |a| { (v.visit_ty)(a.ty, (copy e, v)); } - (v.visit_ty)(f.decl.output, (copy e, v)); + for f.decl.inputs.iter().advance |a| { (v.visit_ty)(&a.ty, (copy e, v)); } + (v.visit_ty)(&f.decl.output, (copy e, v)); do f.bounds.map |bounds| { visit_ty_param_bounds(bounds, (copy e, v)); }; }, ty_bare_fn(ref f) => { - for f.decl.inputs.iter().advance |a| { (v.visit_ty)(a.ty, (copy e, v)); } - (v.visit_ty)(f.decl.output, (e, v)); + for f.decl.inputs.iter().advance |a| { (v.visit_ty)(&a.ty, (copy e, v)); } + (v.visit_ty)(&f.decl.output, (e, v)); }, ty_path(ref p, ref bounds, _) => { visit_path(p, (copy e, v)); @@ -267,7 +267,7 @@ pub fn visit_ty(t: &Ty, (e, v): (E, vt)) { } pub fn visit_path(p: &Path, (e, v): (E, vt)) { - for p.types.iter().advance |tp| { (v.visit_ty)(*tp, (copy e, v)); } + for p.types.iter().advance |tp| { (v.visit_ty)(tp, (copy e, v)); } } pub fn visit_pat(p: &pat, (e, v): (E, vt)) { @@ -326,7 +326,7 @@ pub fn visit_foreign_item(ni: &foreign_item, (e, v): (E, vt)) { visit_fn_decl(fd, (copy e, v)); (v.visit_generics)(generics, (e, v)); } - foreign_item_static(t, _) => { + foreign_item_static(ref t, _) => { (v.visit_ty)(t, (e, v)); } } @@ -351,9 +351,9 @@ pub fn visit_generics(generics: &Generics, (e, v): (E, vt)) { pub fn visit_fn_decl(fd: &fn_decl, (e, v): (E, vt)) { for fd.inputs.iter().advance |a| { (v.visit_pat)(a.pat, (copy e, v)); - (v.visit_ty)(a.ty, (copy e, v)); + (v.visit_ty)(&a.ty, (copy e, v)); } - (v.visit_ty)(fd.output, (e, v)); + (v.visit_ty)(&fd.output, (e, v)); } // Note: there is no visit_method() method in the visitor, instead override @@ -384,9 +384,9 @@ pub fn visit_fn(fk: &fn_kind, decl: &fn_decl, body: &blk, _sp: span, } pub fn visit_ty_method(m: &ty_method, (e, v): (E, vt)) { - for m.decl.inputs.iter().advance |a| { (v.visit_ty)(a.ty, (copy e, v)); } + for m.decl.inputs.iter().advance |a| { (v.visit_ty)(&a.ty, (copy e, v)); } (v.visit_generics)(&m.generics, (copy e, v)); - (v.visit_ty)(m.decl.output, (e, v)); + (v.visit_ty)(&m.decl.output, (e, v)); } pub fn visit_trait_method(m: &trait_method, (e, v): (E, vt)) { @@ -409,7 +409,7 @@ pub fn visit_struct_def( } pub fn visit_struct_field(sf: &struct_field, (e, v): (E, vt)) { - (v.visit_ty)(sf.node.ty, (e, v)); + (v.visit_ty)(&sf.node.ty, (e, v)); } pub fn visit_block(b: &blk, (e, v): (E, vt)) { @@ -475,7 +475,7 @@ pub fn visit_expr(ex: @expr, (e, v): (E, vt)) { expr_method_call(_, callee, _, ref tys, ref args, _) => { visit_exprs(*args, (copy e, v)); for tys.iter().advance |tp| { - (v.visit_ty)(*tp, (copy e, v)); + (v.visit_ty)(tp, (copy e, v)); } (v.visit_expr)(callee, (copy e, v)); } @@ -486,7 +486,7 @@ pub fn visit_expr(ex: @expr, (e, v): (E, vt)) { expr_addr_of(_, x) | expr_unary(_, _, x) | expr_loop_body(x) | expr_do_body(x) => (v.visit_expr)(x, (copy e, v)), expr_lit(_) => (), - expr_cast(x, t) => { + expr_cast(x, ref t) => { (v.visit_expr)(x, (copy e, v)); (v.visit_ty)(t, (copy e, v)); } @@ -527,7 +527,7 @@ pub fn visit_expr(ex: @expr, (e, v): (E, vt)) { expr_field(x, _, ref tys) => { (v.visit_expr)(x, (copy e, v)); for tys.iter().advance |tp| { - (v.visit_ty)(*tp, (copy e, v)); + (v.visit_ty)(tp, (copy e, v)); } } expr_index(_, a, b) => { @@ -579,7 +579,7 @@ pub struct SimpleVisitor { visit_decl: @fn(@decl), visit_expr: @fn(@expr), visit_expr_post: @fn(@expr), - visit_ty: @fn(@Ty), + visit_ty: @fn(&Ty), visit_generics: @fn(&Generics), visit_fn: @fn(&fn_kind, &fn_decl, &blk, span, node_id), visit_ty_method: @fn(&ty_method), @@ -591,7 +591,7 @@ pub struct SimpleVisitor { pub type simple_visitor = @SimpleVisitor; -pub fn simple_ignore_ty(_t: @Ty) {} +pub fn simple_ignore_ty(_t: &Ty) {} pub fn default_simple_visitor() -> @SimpleVisitor { @SimpleVisitor { @@ -672,7 +672,7 @@ pub fn mk_simple_visitor(v: simple_visitor) -> vt<()> { fn v_expr_post(f: @fn(@expr), ex: @expr, (_e, _v): ((), vt<()>)) { f(ex); } - fn v_ty(f: @fn(@Ty), ty: @Ty, (e, v): ((), vt<()>)) { + fn v_ty(f: @fn(&Ty), ty: &Ty, (e, v): ((), vt<()>)) { f(ty); visit_ty(ty, (e, v)); } @@ -717,7 +717,7 @@ pub fn mk_simple_visitor(v: simple_visitor) -> vt<()> { f(fk, decl, body, sp, id); visit_fn(fk, decl, body, sp, id, (e, v)); } - let visit_ty: @fn(@Ty, ((), vt<()>)) = + let visit_ty: @fn(&Ty, ((), vt<()>)) = |a,b| v_ty(v.visit_ty, a, b); fn v_struct_field(f: @fn(@struct_field), sf: @struct_field, (e, v): ((), vt<()>)) { f(sf); From 7ce68dc9e1c47f5f7d297bc3094e21c9e3c9fd34 Mon Sep 17 00:00:00 2001 From: James Miller Date: Sat, 6 Jul 2013 18:40:58 +1200 Subject: [PATCH 79/93] Clean up warnings --- src/librustc/middle/trans/common.rs | 3 --- src/librustc/middle/trans/meth.rs | 1 - src/librustc/middle/trans/uniq.rs | 1 - src/librustc/middle/typeck/check/mod.rs | 2 -- src/librustc/middle/typeck/check/regionck.rs | 8 +------- src/librustc/middle/typeck/infer/combine.rs | 3 +-- src/librustc/middle/typeck/infer/error_reporting.rs | 7 +------ src/librustc/middle/typeck/infer/glb.rs | 3 +-- src/librustc/middle/typeck/infer/lub.rs | 2 -- src/librustc/middle/typeck/infer/mod.rs | 2 +- src/librustc/middle/typeck/infer/region_inference/mod.rs | 3 +-- src/librustc/middle/typeck/infer/sub.rs | 3 +-- 12 files changed, 7 insertions(+), 31 deletions(-) diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 865fb26b9455..1030af978786 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -34,9 +34,6 @@ use std::cast::transmute; use std::cast; use std::hashmap::{HashMap}; use std::libc::{c_uint, c_longlong, c_ulonglong}; -use std::to_bytes; -use std::str; -use std::vec::raw::to_ptr; use std::vec; use syntax::ast::ident; use syntax::ast_map::{path, path_elt}; diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 65271faa7b08..ca469a42103a 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -548,7 +548,6 @@ pub fn trans_trait_callee_from_llval(bcx: block, let _icx = push_ctxt("impl::trans_trait_callee"); let ccx = bcx.ccx(); - let mut bcx = bcx; // Load the vtable from the @Trait pair debug!("(translating trait callee) loading vtable from pair %s", diff --git a/src/librustc/middle/trans/uniq.rs b/src/librustc/middle/trans/uniq.rs index ada85c82b304..adecd61bc4f4 100644 --- a/src/librustc/middle/trans/uniq.rs +++ b/src/librustc/middle/trans/uniq.rs @@ -9,7 +9,6 @@ // except according to those terms. -use back; use lib::llvm::ValueRef; use middle::trans::base::*; use middle::trans::build::*; diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 51159c0391a1..5c8ce6b2d8bb 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -463,7 +463,6 @@ pub fn check_fn(ccx: @mut CrateCtxt, } // Check the pattern. - let region = fcx.block_region(); let pcx = pat_ctxt { fcx: fcx, map: pat_id_map(tcx.def_map, input.pat), @@ -2892,7 +2891,6 @@ pub fn check_decl_local(fcx: @mut FnCtxt, local: @ast::local) { _ => {} } - let region = tcx.region_maps.encl_region(local.node.id); let pcx = pat_ctxt { fcx: fcx, map: pat_id_map(tcx.def_map, local.node.pat), diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index 2e41649e4dbb..65b40fbd48c5 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -36,11 +36,9 @@ use middle::typeck::check::regionmanip::relate_nested_regions; use middle::typeck::infer::resolve_and_force_all_but_regions; use middle::typeck::infer::resolve_type; use middle::typeck::infer; -use util::ppaux::{note_and_explain_region, ty_to_str, - region_to_str}; +use util::ppaux::{ty_to_str, region_to_str}; use middle::pat_util; -use std::result; use std::uint; use syntax::ast::{ManagedSigil, OwnedSigil, BorrowedSigil}; use syntax::ast::{def_arg, def_binding, def_local, def_self, def_upvar}; @@ -419,8 +417,6 @@ fn constrain_callee(rcx: @mut Rcx, call_expr: @ast::expr, callee_expr: @ast::expr) { - let tcx = rcx.fcx.tcx(); - let call_region = ty::re_scope(call_expr.id); let callee_ty = rcx.resolve_node_type(callee_id); @@ -559,8 +555,6 @@ fn constrain_index(rcx: @mut Rcx, * includes the deref expr. */ - let tcx = rcx.fcx.tcx(); - debug!("constrain_index(index_expr=?, indexed_ty=%s", rcx.fcx.infcx().ty_to_str(indexed_ty)); diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs index f03f01732291..ee90d9661c37 100644 --- a/src/librustc/middle/typeck/infer/combine.rs +++ b/src/librustc/middle/typeck/infer/combine.rs @@ -65,7 +65,7 @@ use middle::typeck::infer::sub::Sub; use middle::typeck::infer::to_str::InferStr; use middle::typeck::infer::unify::{InferCtxtMethods}; use middle::typeck::infer::{InferCtxt, cres, ures}; -use middle::typeck::infer::{TypeOrigin, TypeTrace}; +use middle::typeck::infer::{TypeTrace}; use util::common::indent; use std::result::{iter_vec2, map_vec2}; @@ -73,7 +73,6 @@ use std::vec; use syntax::ast::{Onceness, purity}; use syntax::ast; use syntax::opt_vec; -use syntax::codemap::span; use syntax::abi::AbiSet; pub trait Combine { diff --git a/src/librustc/middle/typeck/infer/error_reporting.rs b/src/librustc/middle/typeck/infer/error_reporting.rs index e533f019b469..928f33803dd8 100644 --- a/src/librustc/middle/typeck/infer/error_reporting.rs +++ b/src/librustc/middle/typeck/infer/error_reporting.rs @@ -59,23 +59,18 @@ time of error detection. */ -use std::prelude::*; use middle::ty; use middle::ty::Region; use middle::typeck::infer; use middle::typeck::infer::InferCtxt; use middle::typeck::infer::TypeTrace; -use middle::typeck::infer::TypeOrigin; use middle::typeck::infer::SubregionOrigin; use middle::typeck::infer::RegionVariableOrigin; -use middle::typeck::infer::Types; -use middle::typeck::infer::TraitRefs; use middle::typeck::infer::ValuePairs; use middle::typeck::infer::region_inference::RegionResolutionError; use middle::typeck::infer::region_inference::ConcreteFailure; use middle::typeck::infer::region_inference::SubSupConflict; use middle::typeck::infer::region_inference::SupSupConflict; -use syntax::opt_vec; use syntax::opt_vec::OptVec; use util::ppaux::UserString; use util::ppaux::note_and_explain_region; @@ -362,7 +357,7 @@ impl ErrorReporting for InferCtxt { sup, ""); } - infer::ReferenceOutlivesReferent(ty, span) => { + infer::ReferenceOutlivesReferent(ty, _) => { self.tcx.sess.span_err( origin.span(), fmt!("in type `%s`, pointer has a longer lifetime than \ diff --git a/src/librustc/middle/typeck/infer/glb.rs b/src/librustc/middle/typeck/infer/glb.rs index fefbf2336c29..32f3e8fea3a8 100644 --- a/src/librustc/middle/typeck/infer/glb.rs +++ b/src/librustc/middle/typeck/infer/glb.rs @@ -26,8 +26,7 @@ use syntax::ast::{Many, Once, extern_fn, impure_fn, m_const, m_imm, m_mutbl}; use syntax::ast::{unsafe_fn}; use syntax::ast::{Onceness, purity}; use syntax::abi::AbiSet; -use syntax::codemap::span; -use util::common::{indent, indenter}; +use util::common::{indenter}; use util::ppaux::mt_to_str; use extra::list; diff --git a/src/librustc/middle/typeck/infer/lub.rs b/src/librustc/middle/typeck/infer/lub.rs index efb1dc200b52..3f23fd6e7096 100644 --- a/src/librustc/middle/typeck/infer/lub.rs +++ b/src/librustc/middle/typeck/infer/lub.rs @@ -21,7 +21,6 @@ use middle::typeck::infer::{cres, InferCtxt}; use middle::typeck::infer::fold_regions_in_sig; use middle::typeck::infer::{TypeTrace, Subtype}; use middle::typeck::isr_alist; -use util::common::indent; use util::ppaux::mt_to_str; use extra::list; @@ -30,7 +29,6 @@ use syntax::ast; use syntax::ast::{Many, Once, extern_fn, m_const, impure_fn}; use syntax::ast::{unsafe_fn}; use syntax::ast::{Onceness, purity}; -use syntax::codemap::span; pub struct Lub(CombineFields); // least-upper-bound: common supertype diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs index 3360edc6a467..d0a778139dbd 100644 --- a/src/librustc/middle/typeck/infer/mod.rs +++ b/src/librustc/middle/typeck/infer/mod.rs @@ -328,7 +328,7 @@ pub fn can_mk_subty(cx: @mut InferCtxt, a: ty::t, b: ty::t) -> ures { } pub fn mk_subr(cx: @mut InferCtxt, - a_is_expected: bool, + _a_is_expected: bool, origin: SubregionOrigin, a: ty::Region, b: ty::Region) { diff --git a/src/librustc/middle/typeck/infer/region_inference/mod.rs b/src/librustc/middle/typeck/infer/region_inference/mod.rs index 96cb5d3c747c..7bf4d07b7230 100644 --- a/src/librustc/middle/typeck/infer/region_inference/mod.rs +++ b/src/librustc/middle/typeck/infer/region_inference/mod.rs @@ -19,13 +19,12 @@ use middle::typeck::infer::cres; use middle::typeck::infer::{RegionVariableOrigin, SubregionOrigin}; use middle::typeck::infer; use util::common::indenter; -use util::ppaux::{note_and_explain_region, Repr, UserString}; +use util::ppaux::{Repr}; use std::cell::Cell; use std::hashmap::{HashMap, HashSet}; use std::uint; use std::vec; -use syntax::codemap::span; use syntax::ast; use syntax::opt_vec; use syntax::opt_vec::OptVec; diff --git a/src/librustc/middle/typeck/infer/sub.rs b/src/librustc/middle/typeck/infer/sub.rs index 72178500b54e..cfb33732459f 100644 --- a/src/librustc/middle/typeck/infer/sub.rs +++ b/src/librustc/middle/typeck/infer/sub.rs @@ -21,7 +21,7 @@ use middle::typeck::infer::lattice::CombineFieldsLatticeMethods; use middle::typeck::infer::lub::Lub; use middle::typeck::infer::to_str::InferStr; use middle::typeck::infer::{TypeTrace, Subtype}; -use util::common::{indent, indenter}; +use util::common::{indenter}; use util::ppaux::bound_region_to_str; use extra::list::Nil; @@ -29,7 +29,6 @@ use extra::list; use syntax::abi::AbiSet; use syntax::ast; use syntax::ast::{Onceness, m_const, purity}; -use syntax::codemap::span; pub struct Sub(CombineFields); // "subtype", "subregion" etc From fb19205b1bfd565ca11132eb7deb64e0338d5ecd Mon Sep 17 00:00:00 2001 From: James Miller Date: Sat, 6 Jul 2013 18:47:20 +1200 Subject: [PATCH 80/93] Fix rustdoc and rusti --- src/librustdoc/tystr_pass.rs | 11 +++++------ src/librusti/rusti.rs | 2 +- src/librusti/utils.rs | 4 ++-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/librustdoc/tystr_pass.rs b/src/librustdoc/tystr_pass.rs index e40bdb532da9..40c662e3a09e 100644 --- a/src/librustdoc/tystr_pass.rs +++ b/src/librustdoc/tystr_pass.rs @@ -94,7 +94,7 @@ fn fold_const( do astsrv::exec(srv) |ctxt| { match ctxt.ast_map.get_copy(&doc.id()) { ast_map::node_item(@ast::item { - node: ast::item_static(ty, _, _), _ + node: ast::item_static(ref ty, _, _), _ }, _) => { pprust::ty_to_str(ty, extract::interner()) } @@ -245,12 +245,12 @@ fn fold_impl( do astsrv::exec(srv) |ctxt| { match ctxt.ast_map.get_copy(&doc.id()) { ast_map::node_item(@ast::item { - node: ast::item_impl(ref generics, opt_trait_type, self_ty, _), _ + node: ast::item_impl(ref generics, ref opt_trait_type, ref self_ty, _), _ }, _) => { let bounds = pprust::generics_to_str(generics, extract::interner()); let bounds = if bounds.is_empty() { None } else { Some(bounds) }; let trait_types = opt_trait_type.map_default(~[], |p| { - ~[pprust::path_to_str(p.path, extract::interner())] + ~[pprust::path_to_str(&p.path, extract::interner())] }); (bounds, trait_types, @@ -285,15 +285,14 @@ fn fold_type( match ctxt.ast_map.get_copy(&doc.id()) { ast_map::node_item(@ast::item { ident: ident, - node: ast::item_ty(ty, ref params), _ + node: ast::item_ty(ref ty, ref params), _ }, _) => { Some(fmt!( "type %s%s = %s", to_str(ident), pprust::generics_to_str(params, extract::interner()), - pprust::ty_to_str(ty, - extract::interner()) + pprust::ty_to_str(ty, extract::interner()) )) } _ => fail!("expected type") diff --git a/src/librusti/rusti.rs b/src/librusti/rusti.rs index 9911ca699dac..d9cd52201c0c 100644 --- a/src/librusti/rusti.rs +++ b/src/librusti/rusti.rs @@ -132,7 +132,7 @@ fn run(mut repl: Repl, input: ~str) -> Repl { // differently beause they must appear before all 'use' statements for blk.node.view_items.iter().advance |vi| { let s = do with_pp(intr) |pp, _| { - pprust::print_view_item(pp, *vi); + pprust::print_view_item(pp, vi); }; match vi.node { ast::view_item_extern_mod(*) => { diff --git a/src/librusti/utils.rs b/src/librusti/utils.rs index 0ac0f5a3c4cb..3932df1db847 100644 --- a/src/librusti/utils.rs +++ b/src/librusti/utils.rs @@ -14,14 +14,14 @@ use syntax::print::pp; use syntax::print::pprust; use syntax::parse::token; -pub fn each_binding(l: @ast::local, f: @fn(@ast::Path, ast::node_id)) { +pub fn each_binding(l: @ast::local, f: @fn(&ast::Path, ast::node_id)) { use syntax::visit; let vt = visit::mk_simple_visitor( @visit::SimpleVisitor { visit_pat: |pat| { match pat.node { - ast::pat_ident(_, path, _) => { + ast::pat_ident(_, ref path, _) => { f(path, pat.id); } _ => {} From 1fd735d3c1d7aaa9e026ce74ea341a291fce91fd Mon Sep 17 00:00:00 2001 From: James Miller Date: Sun, 7 Jul 2013 10:59:27 +1200 Subject: [PATCH 81/93] Fix broken tests --- src/libsyntax/fold.rs | 6 +++--- src/libsyntax/parse/mod.rs | 10 +++++----- src/libsyntax/print/pprust.rs | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index e2beebcead26..c36b717ea005 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -964,7 +964,7 @@ mod test { } // this version doesn't care about getting comments or docstrings in. - fn fake_print_crate(s: @pprust::ps, crate: ast::crate) { + fn fake_print_crate(s: @pprust::ps, crate: &ast::crate) { pprust::print_mod(s, &crate.node.module, crate.node.attrs); } @@ -995,7 +995,7 @@ mod test { let ast = string_to_crate(@"#[a] mod b {fn c (d : e, f : g) {h!(i,j,k);l;m}}"); assert_pred!(matches_codepattern, "matches_codepattern", - pprust::to_str(zz_fold.fold_crate(ast),fake_print_crate, + pprust::to_str(&zz_fold.fold_crate(ast),fake_print_crate, token::get_ident_interner()), ~"#[a]mod zz{fn zz(zz:zz,zz:zz){zz!(zz,zz,zz);zz;zz}}"); } @@ -1007,7 +1007,7 @@ mod test { => (g $(d $d $e)+))} "); assert_pred!(matches_codepattern, "matches_codepattern", - pprust::to_str(zz_fold.fold_crate(ast),fake_print_crate, + pprust::to_str(&zz_fold.fold_crate(ast),fake_print_crate, token::get_ident_interner()), ~"zz!zz((zz$zz:zz$(zz $zz:zz)zz+=>(zz$(zz$zz$zz)+)))"); } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 634efbe165da..fdf3f0e639ea 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -482,7 +482,7 @@ mod test { assert_eq!(parser.parse_arg_general(true), ast::arg{ is_mutbl: false, - ty: @ast::Ty{id:3, // fixme + ty: ast::Ty{id:3, // fixme node: ast::ty_path(ast::Path{ span:sp(4,4), // this is bizarre... // check this in the original parser? @@ -490,7 +490,7 @@ mod test { idents:~[str_to_ident("int")], rp: None, types: ~[]}, - @None, 2), + None, 2), span:sp(4,7)}, pat: @ast::pat{id:1, node: ast::pat_ident(ast::bind_infer, @@ -519,14 +519,14 @@ mod test { node: ast::item_fn(ast::fn_decl{ inputs: ~[ast::arg{ is_mutbl: false, - ty: @ast::Ty{id:3, // fixme + ty: ast::Ty{id:3, // fixme node: ast::ty_path(ast::Path{ span:sp(10,13), global:false, idents:~[str_to_ident("int")], rp: None, types: ~[]}, - @None, 2), + None, 2), span:sp(10,13)}, pat: @ast::pat{id:1, // fixme node: ast::pat_ident( @@ -542,7 +542,7 @@ mod test { span: sp(6,7)}, id: 4 // fixme }], - output: @ast::Ty{id:5, // fixme + output: ast::Ty{id:5, // fixme node: ast::ty_nil, span:sp(15,15)}, // not sure cf: ast::return_val diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 517065ab1b5c..b545c56778e9 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -2272,7 +2272,7 @@ mod test { let decl = ast::fn_decl { inputs: ~[], - output: @ast::Ty {id: 0, + output: ast::Ty {id: 0, node: ast::ty_nil, span: codemap::dummy_sp()}, cf: ast::return_val From 280e4245c065da9c22b09c1d18c0629af1709eb3 Mon Sep 17 00:00:00 2001 From: James Miller Date: Sun, 7 Jul 2013 23:05:03 +1200 Subject: [PATCH 82/93] Fix merge-fallout-typo --- src/librustc/middle/resolve.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 861c61e497aa..041d52a69042 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -3822,7 +3822,7 @@ impl Resolver { trait_reference: &trait_ref, visitor: ResolveVisitor, reference_type: TraitReferenceType) { - match self.resolve_path(trait_reference.path, TypeNS, true, visitor) { + match self.resolve_path(&trait_reference.path, TypeNS, true, visitor) { None => { let path_str = self.idents_to_str(trait_reference.path.idents); From e41e4358516190bf84172f21d9e25e45da81caf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Sun, 7 Jul 2013 14:53:57 +0200 Subject: [PATCH 83/93] Implement scopes independent of LLVM basic blocks Currently, scopes are tied to LLVM basic blocks. For each scope, there are two new basic blocks, which means two extra jumps in the unoptimized IR. These blocks aren't actually required, but only used to act as the boundary for cleanups. By keeping track of the current scope within a single basic block, we can avoid those extra blocks and jumps, shrinking the pre-optimization IR quite considerably. For example, the IR for trans_intrinsic goes from ~22k lines to ~16k lines, almost 30% less. The impact on the build times of optimized builds is rather small (about 1%), but unoptimized builds are about 11% faster. The testsuite for unoptimized builds runs between 15% (CPU time) and 7.5% (wallclock time on my i7) faster. Also, in some situations this helps LLVM to generate better code by inlining functions that it previously considered to be too large. Likely because of the pointless blocks/jumps that were still present at the time the inlining pass runs. Refs #7462 --- src/librustc/middle/trans/base.rs | 196 +++++++++++++---------- src/librustc/middle/trans/common.rs | 90 ++++++----- src/librustc/middle/trans/controlflow.rs | 74 +++++---- src/librustc/middle/trans/write_guard.rs | 4 +- 4 files changed, 203 insertions(+), 161 deletions(-) diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index d6105cc1dded..d3ff63a959bd 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -863,10 +863,10 @@ pub fn need_invoke(bcx: block) -> bool { // Walk the scopes to look for cleanups let mut cur = bcx; + let mut cur_scope = cur.scope; loop { - match cur.kind { - block_scope(inf) => { - let inf = &mut *inf; // FIXME(#5074) workaround old borrowck + cur_scope = match cur_scope { + Some(inf) => { for inf.cleanups.iter().advance |cleanup| { match *cleanup { clean(_, cleanup_type) | clean_temp(_, _, cleanup_type) => { @@ -876,12 +876,15 @@ pub fn need_invoke(bcx: block) -> bool { } } } + inf.parent + } + None => { + cur = match cur.parent { + Some(next) => next, + None => return false + }; + cur.scope } - _ => () - } - cur = match cur.parent { - Some(next) => next, - None => return false } } } @@ -899,23 +902,21 @@ pub fn have_cached_lpad(bcx: block) -> bool { pub fn in_lpad_scope_cx(bcx: block, f: &fn(si: &mut scope_info)) { let mut bcx = bcx; + let mut cur_scope = bcx.scope; loop { - { - match bcx.kind { - block_scope(inf) => { - let len = { // FIXME(#5074) workaround old borrowck - let inf = &mut *inf; - inf.cleanups.len() - }; - if len > 0u || bcx.parent.is_none() { - f(inf); - return; - } + cur_scope = match cur_scope { + Some(inf) => { + if !inf.empty_cleanups() || (inf.parent.is_none() && bcx.parent.is_none()) { + f(inf); + return; } - _ => () + inf.parent + } + None => { + bcx = block_parent(bcx); + bcx.scope } } - bcx = block_parent(bcx); } } @@ -972,27 +973,31 @@ pub fn get_landing_pad(bcx: block) -> BasicBlockRef { pub fn find_bcx_for_scope(bcx: block, scope_id: ast::node_id) -> block { let mut bcx_sid = bcx; + let mut cur_scope = bcx_sid.scope; loop { - bcx_sid = match bcx_sid.node_info { - Some(NodeInfo { id, _ }) if id == scope_id => { - return bcx_sid - } - - // FIXME(#6268, #6248) hacky cleanup for nested method calls - Some(NodeInfo { callee_id: Some(id), _ }) if id == scope_id => { - return bcx_sid - } - - _ => { - match bcx_sid.parent { - None => bcx.tcx().sess.bug( - fmt!("no enclosing scope with id %d", scope_id)), - Some(bcx_par) => bcx_par + cur_scope = match cur_scope { + Some(inf) => { + match inf.node_info { + Some(NodeInfo { id, _ }) if id == scope_id => { + return bcx_sid } + // FIXME(#6268, #6248) hacky cleanup for nested method calls + Some(NodeInfo { callee_id: Some(id), _ }) if id == scope_id => { + return bcx_sid + } + _ => inf.parent } } + None => { + bcx_sid = match bcx_sid.parent { + None => bcx.tcx().sess.bug(fmt!("no enclosing scope with id %d", scope_id)), + Some(bcx_par) => bcx_par + }; + bcx_sid.scope + } } } +} pub fn do_spill(bcx: block, v: ValueRef, t: ty::t) -> ValueRef { @@ -1145,7 +1150,7 @@ pub fn trans_stmt(cx: block, s: &ast::stmt) -> block { // You probably don't want to use this one. See the // next three functions instead. -pub fn new_block(cx: fn_ctxt, parent: Option, kind: block_kind, +pub fn new_block(cx: fn_ctxt, parent: Option, scope: Option<@mut scope_info>, is_lpad: bool, name: &str, opt_node_info: Option) -> block { @@ -1155,10 +1160,10 @@ pub fn new_block(cx: fn_ctxt, parent: Option, kind: block_kind, }; let bcx = mk_block(llbb, parent, - kind, is_lpad, opt_node_info, cx); + bcx.scope = scope; for parent.iter().advance |cx| { if cx.unreachable { Unreachable(bcx); @@ -1169,27 +1174,30 @@ pub fn new_block(cx: fn_ctxt, parent: Option, kind: block_kind, } } -pub fn simple_block_scope() -> block_kind { - block_scope(@mut scope_info { +pub fn simple_block_scope(parent: Option<@mut scope_info>, + node_info: Option) -> @mut scope_info { + @mut scope_info { + parent: parent, loop_break: None, loop_label: None, cleanups: ~[], cleanup_paths: ~[], - landing_pad: None - }) + landing_pad: None, + node_info: node_info, + } } // Use this when you're at the top block of a function or the like. pub fn top_scope_block(fcx: fn_ctxt, opt_node_info: Option) -> block { - return new_block(fcx, None, simple_block_scope(), false, + return new_block(fcx, None, Some(simple_block_scope(None, opt_node_info)), false, "function top level", opt_node_info); } pub fn scope_block(bcx: block, opt_node_info: Option, n: &str) -> block { - return new_block(bcx.fcx, Some(bcx), simple_block_scope(), bcx.is_lpad, + return new_block(bcx.fcx, Some(bcx), Some(simple_block_scope(None, opt_node_info)), bcx.is_lpad, n, opt_node_info); } @@ -1198,27 +1206,29 @@ pub fn loop_scope_block(bcx: block, loop_label: Option, n: &str, opt_node_info: Option) -> block { - return new_block(bcx.fcx, Some(bcx), block_scope(@mut scope_info { + return new_block(bcx.fcx, Some(bcx), Some(@mut scope_info { + parent: None, loop_break: Some(loop_break), loop_label: loop_label, cleanups: ~[], cleanup_paths: ~[], - landing_pad: None + landing_pad: None, + node_info: opt_node_info, }), bcx.is_lpad, n, opt_node_info); } // Use this when creating a block for the inside of a landing pad. pub fn lpad_block(bcx: block, n: &str) -> block { - new_block(bcx.fcx, Some(bcx), block_non_scope, true, n, None) + new_block(bcx.fcx, Some(bcx), None, true, n, None) } // Use this when you're making a general CFG BB within a scope. pub fn sub_block(bcx: block, n: &str) -> block { - new_block(bcx.fcx, Some(bcx), block_non_scope, bcx.is_lpad, n, None) + new_block(bcx.fcx, Some(bcx), None, bcx.is_lpad, n, None) } pub fn raw_block(fcx: fn_ctxt, is_lpad: bool, llbb: BasicBlockRef) -> block { - mk_block(llbb, None, block_non_scope, is_lpad, None, fcx) + mk_block(llbb, None, is_lpad, None, fcx) } @@ -1277,42 +1287,47 @@ pub fn cleanup_and_leave(bcx: block, (fmt!("cleanup_and_leave(%s)", cur.to_str())).to_managed()); } - match cur.kind { - block_scope(inf) if !inf.empty_cleanups() => { - let (sub_cx, dest, inf_cleanups) = { - let inf = &mut *inf; - let mut skip = 0; - let mut dest = None; - { - let r = (*inf).cleanup_paths.rev_iter().find_(|cp| cp.target == leave); - for r.iter().advance |cp| { - if cp.size == inf.cleanups.len() { - Br(bcx, cp.dest); - return; - } + let mut cur_scope = cur.scope; + loop { + cur_scope = match cur_scope { + Some (inf) if !inf.empty_cleanups() => { + let (sub_cx, dest, inf_cleanups) = { + let inf = &mut *inf; + let mut skip = 0; + let mut dest = None; + { + let r = (*inf).cleanup_paths.rev_iter().find_(|cp| cp.target == leave); + for r.iter().advance |cp| { + if cp.size == inf.cleanups.len() { + Br(bcx, cp.dest); + return; + } - skip = cp.size; - dest = Some(cp.dest); + skip = cp.size; + dest = Some(cp.dest); + } } + let sub_cx = sub_block(bcx, "cleanup"); + Br(bcx, sub_cx.llbb); + inf.cleanup_paths.push(cleanup_path { + target: leave, + size: inf.cleanups.len(), + dest: sub_cx.llbb + }); + (sub_cx, dest, inf.cleanups.tailn(skip).to_owned()) + }; + bcx = trans_block_cleanups_(sub_cx, + inf_cleanups, + is_lpad); + for dest.iter().advance |&dest| { + Br(bcx, dest); + return; } - let sub_cx = sub_block(bcx, "cleanup"); - Br(bcx, sub_cx.llbb); - inf.cleanup_paths.push(cleanup_path { - target: leave, - size: inf.cleanups.len(), - dest: sub_cx.llbb - }); - (sub_cx, dest, inf.cleanups.tailn(skip).to_owned()) - }; - bcx = trans_block_cleanups_(sub_cx, - inf_cleanups, - is_lpad); - for dest.iter().advance |&dest| { - Br(bcx, dest); - return; + inf.parent } + Some(inf) => inf.parent, + None => break } - _ => () } match upto { @@ -1353,9 +1368,12 @@ pub fn with_scope(bcx: block, bcx.to_str(), opt_node_info, name); let _indenter = indenter(); - let scope_cx = scope_block(bcx, opt_node_info, name); - Br(bcx, scope_cx.llbb); - leave_block(f(scope_cx), scope_cx) + let scope = simple_block_scope(bcx.scope, opt_node_info); + bcx.scope = Some(scope); + let ret = f(bcx); + let ret = trans_block_cleanups_(ret, /*bad*/copy scope.cleanups, false); + bcx.scope = scope.parent; + ret } pub fn with_scope_result(bcx: block, @@ -1363,10 +1381,14 @@ pub fn with_scope_result(bcx: block, name: &str, f: &fn(block) -> Result) -> Result { let _icx = push_ctxt("with_scope_result"); - let scope_cx = scope_block(bcx, opt_node_info, name); - Br(bcx, scope_cx.llbb); - let Result {bcx, val} = f(scope_cx); - rslt(leave_block(bcx, scope_cx), val) + + let scope = simple_block_scope(bcx.scope, opt_node_info); + bcx.scope = Some(scope); + let Result { bcx: out_bcx, val } = f(bcx); + let out_bcx = trans_block_cleanups_(out_bcx, /*bad*/copy scope.cleanups, false); + bcx.scope = scope.parent; + + rslt(out_bcx, val) } pub fn with_scope_datumblock(bcx: block, opt_node_info: Option, diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 865fb26b9455..11859947e1e9 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -321,7 +321,7 @@ pub fn add_clean(bcx: block, val: ValueRef, t: ty::t) { debug!("add_clean(%s, %s, %s)", bcx.to_str(), bcx.val_to_str(val), t.repr(bcx.tcx())); let cleanup_type = cleanup_type(bcx.tcx(), t); - do in_scope_cx(bcx) |scope_info| { + do in_scope_cx(bcx, None) |scope_info| { scope_info.cleanups.push(clean(|a| glue::drop_ty(a, val, t), cleanup_type)); grow_scope_clean(scope_info); } @@ -333,25 +333,36 @@ pub fn add_clean_temp_immediate(cx: block, val: ValueRef, ty: ty::t) { cx.to_str(), cx.val_to_str(val), ty.repr(cx.tcx())); let cleanup_type = cleanup_type(cx.tcx(), ty); - do in_scope_cx(cx) |scope_info| { + do in_scope_cx(cx, None) |scope_info| { scope_info.cleanups.push( clean_temp(val, |a| glue::drop_ty_immediate(a, val, ty), cleanup_type)); grow_scope_clean(scope_info); } } + pub fn add_clean_temp_mem(bcx: block, val: ValueRef, t: ty::t) { + add_clean_temp_mem_in_scope_(bcx, None, val, t); +} + +pub fn add_clean_temp_mem_in_scope(bcx: block, scope_id: ast::node_id, val: ValueRef, t: ty::t) { + add_clean_temp_mem_in_scope_(bcx, Some(scope_id), val, t); +} + +pub fn add_clean_temp_mem_in_scope_(bcx: block, scope_id: Option, + val: ValueRef, t: ty::t) { if !ty::type_needs_drop(bcx.tcx(), t) { return; } debug!("add_clean_temp_mem(%s, %s, %s)", bcx.to_str(), bcx.val_to_str(val), t.repr(bcx.tcx())); let cleanup_type = cleanup_type(bcx.tcx(), t); - do in_scope_cx(bcx) |scope_info| { + do in_scope_cx(bcx, scope_id) |scope_info| { scope_info.cleanups.push(clean_temp(val, |a| glue::drop_ty(a, val, t), cleanup_type)); grow_scope_clean(scope_info); } } pub fn add_clean_return_to_mut(bcx: block, + scope_id: ast::node_id, root_key: root_map_key, frozen_val_ref: ValueRef, bits_val_ref: ValueRef, @@ -369,7 +380,7 @@ pub fn add_clean_return_to_mut(bcx: block, bcx.to_str(), bcx.val_to_str(frozen_val_ref), bcx.val_to_str(bits_val_ref)); - do in_scope_cx(bcx) |scope_info| { + do in_scope_cx(bcx, Some(scope_id)) |scope_info| { scope_info.cleanups.push( clean_temp( frozen_val_ref, @@ -390,7 +401,7 @@ pub fn add_clean_free(cx: block, ptr: ValueRef, heap: heap) { f } }; - do in_scope_cx(cx) |scope_info| { + do in_scope_cx(cx, None) |scope_info| { scope_info.cleanups.push(clean_temp(ptr, free_fn, normal_exit_and_unwind)); grow_scope_clean(scope_info); @@ -402,7 +413,7 @@ pub fn add_clean_free(cx: block, ptr: ValueRef, heap: heap) { // this will be more involved. For now, we simply zero out the local, and the // drop glue checks whether it is zero. pub fn revoke_clean(cx: block, val: ValueRef) { - do in_scope_cx(cx) |scope_info| { + do in_scope_cx(cx, None) |scope_info| { let cleanup_pos = scope_info.cleanups.iter().position_( |cu| match *cu { clean_temp(v, _, _) if v == val => true, @@ -419,27 +430,14 @@ pub fn revoke_clean(cx: block, val: ValueRef) { } pub fn block_cleanups(bcx: block) -> ~[cleanup] { - match bcx.kind { - block_non_scope => ~[], - block_scope(inf) => /*bad*/copy inf.cleanups + match bcx.scope { + None => ~[], + Some(inf) => /*bad*/copy inf.cleanups } } -pub enum block_kind { - // A scope at the end of which temporary values created inside of it are - // cleaned up. May correspond to an actual block in the language, but also - // to an implicit scope, for example, calls introduce an implicit scope in - // which the arguments are evaluated and cleaned up. - block_scope(@mut scope_info), - - // A non-scope block is a basic block created as a translation artifact - // from translating code that expresses conditional logic rather than by - // explicit { ... } block structure in the source language. It's called a - // non-scope block because it doesn't introduce a new variable scope. - block_non_scope, -} - pub struct scope_info { + parent: Option<@mut scope_info>, loop_break: Option, loop_label: Option, // A list of functions that must be run at when leaving this @@ -451,6 +449,8 @@ pub struct scope_info { cleanup_paths: ~[cleanup_path], // Unwinding landing pad. Also cleared when cleanups change. landing_pad: Option, + // info about the AST node this scope originated from, if any + node_info: Option, } impl scope_info { @@ -506,8 +506,8 @@ pub struct block_ { terminated: bool, unreachable: bool, parent: Option, - // The 'kind' of basic block this is. - kind: block_kind, + // The current scope within this basic block + scope: Option<@mut scope_info>, // Is this block part of a landing pad? is_lpad: bool, // info about the AST node this block originated from, if any @@ -517,7 +517,7 @@ pub struct block_ { fcx: fn_ctxt } -pub fn block_(llbb: BasicBlockRef, parent: Option, kind: block_kind, +pub fn block_(llbb: BasicBlockRef, parent: Option, is_lpad: bool, node_info: Option, fcx: fn_ctxt) -> block_ { @@ -526,7 +526,7 @@ pub fn block_(llbb: BasicBlockRef, parent: Option, kind: block_kind, terminated: false, unreachable: false, parent: parent, - kind: kind, + scope: None, is_lpad: is_lpad, node_info: node_info, fcx: fcx @@ -535,10 +535,10 @@ pub fn block_(llbb: BasicBlockRef, parent: Option, kind: block_kind, pub type block = @mut block_; -pub fn mk_block(llbb: BasicBlockRef, parent: Option, kind: block_kind, +pub fn mk_block(llbb: BasicBlockRef, parent: Option, is_lpad: bool, node_info: Option, fcx: fn_ctxt) -> block { - @mut block_(llbb, parent, kind, is_lpad, node_info, fcx) + @mut block_(llbb, parent, is_lpad, node_info, fcx) } pub struct Result { @@ -563,19 +563,33 @@ pub fn val_ty(v: ValueRef) -> Type { } } -pub fn in_scope_cx(cx: block, f: &fn(si: &mut scope_info)) { +pub fn in_scope_cx(cx: block, scope_id: Option, f: &fn(si: &mut scope_info)) { let mut cur = cx; + let mut cur_scope = cur.scope; loop { - match cur.kind { - block_scope(inf) => { - debug!("in_scope_cx: selected cur=%s (cx=%s)", - cur.to_str(), cx.to_str()); - f(inf); - return; + cur_scope = match cur_scope { + Some(inf) => match scope_id { + Some(wanted) => match inf.node_info { + Some(NodeInfo { id: actual, _ }) if wanted == actual => { + debug!("in_scope_cx: selected cur=%s (cx=%s)", + cur.to_str(), cx.to_str()); + f(inf); + return; + }, + _ => inf.parent, + }, + None => { + debug!("in_scope_cx: selected cur=%s (cx=%s)", + cur.to_str(), cx.to_str()); + f(inf); + return; + } + }, + None => { + cur = block_parent(cur); + cur.scope } - _ => () } - cur = block_parent(cur); } } diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs index 75b1830778b1..db6a954ee911 100644 --- a/src/librustc/middle/trans/controlflow.rs +++ b/src/librustc/middle/trans/controlflow.rs @@ -249,42 +249,48 @@ pub fn trans_break_cont(bcx: block, let _icx = push_ctxt("trans_break_cont"); // Locate closest loop block, outputting cleanup as we go. let mut unwind = bcx; - let mut target; + let mut cur_scope = unwind.scope; + let mut target = unwind; + let mut quit = false; loop { - match unwind.kind { - block_scope(@scope_info { - loop_break: Some(brk), - loop_label: l, - _ - }) => { - // If we're looking for a labeled loop, check the label... - target = if to_end { - brk - } else { - unwind - }; - match opt_label { - Some(desired) => match l { - Some(actual) if actual == desired => break, - // If it doesn't match the one we want, - // don't break - _ => () - }, - None => break - } - } - _ => () + cur_scope = match cur_scope { + Some(@scope_info { + loop_break: Some(brk), + loop_label: l, + parent, + _ + }) => { + // If we're looking for a labeled loop, check the label... + target = if to_end { + brk + } else { + unwind + }; + match opt_label { + Some(desired) => match l { + Some(actual) if actual == desired => break, + // If it doesn't match the one we want, + // don't break + _ => parent, + }, + None => break, + } + } + Some(inf) => inf.parent, + None => { + unwind = match unwind.parent { + Some(bcx) => bcx, + // This is a return from a loop body block + None => { + Store(bcx, C_bool(!to_end), bcx.fcx.llretptr.get()); + cleanup_and_leave(bcx, None, Some(bcx.fcx.llreturn)); + Unreachable(bcx); + return bcx; + } + }; + unwind.scope + } } - unwind = match unwind.parent { - Some(bcx) => bcx, - // This is a return from a loop body block - None => { - Store(bcx, C_bool(!to_end), bcx.fcx.llretptr.get()); - cleanup_and_leave(bcx, None, Some(bcx.fcx.llreturn)); - Unreachable(bcx); - return bcx; - } - }; } cleanup_and_Br(bcx, unwind, target.llbb); Unreachable(bcx); diff --git a/src/librustc/middle/trans/write_guard.rs b/src/librustc/middle/trans/write_guard.rs index 068ce4e2b33b..0db770b6c8bc 100644 --- a/src/librustc/middle/trans/write_guard.rs +++ b/src/librustc/middle/trans/write_guard.rs @@ -123,7 +123,7 @@ fn root(datum: &Datum, let scratch = scratch_datum(bcx, datum.ty, true); datum.copy_to_datum(bcx, INIT, scratch); let cleanup_bcx = find_bcx_for_scope(bcx, root_info.scope); - add_clean_temp_mem(cleanup_bcx, scratch.val, scratch.ty); + add_clean_temp_mem_in_scope(cleanup_bcx, root_info.scope, scratch.val, scratch.ty); // Now, consider also freezing it. match root_info.freeze { @@ -168,7 +168,7 @@ fn root(datum: &Datum, } add_clean_return_to_mut( - cleanup_bcx, root_key, scratch.val, scratch_bits.val, + cleanup_bcx, root_info.scope, root_key, scratch.val, scratch_bits.val, filename, line); } } From 7bb4ff62672178c220a945129a2110b91f78d47f Mon Sep 17 00:00:00 2001 From: Andrew Paseltiner Date: Fri, 5 Jul 2013 13:00:11 -0400 Subject: [PATCH 84/93] iterator: Add `IteratorUtil::peek_` method --- src/libstd/iterator.rs | 65 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index b164bcbd28b3..08ccf4fc2553 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -245,6 +245,25 @@ pub trait IteratorUtil { fn flat_map_<'r, B, U: Iterator>(self, f: &'r fn(A) -> U) -> FlatMapIterator<'r, A, B, Self, U>; + /// Creates an iterator that calls a function with a reference to each + /// element before yielding it. This is often useful for debugging an + /// iterator pipeline. + /// + /// # Example + /// + /// ~~~ {.rust} + ///let xs = [1u, 4, 2, 3, 8, 9, 6]; + ///let sum = xs.iter() + /// .transform(|&x| x) + /// .peek_(|&x| debug!("filtering %u", x)) + /// .filter(|&x| x % 2 == 0) + /// .peek_(|&x| debug!("%u made it through", x)) + /// .sum(); + ///println(sum.to_str()); + /// ~~~ + // FIXME: #5898: should be called `peek` + fn peek_<'r>(self, f: &'r fn(&A)) -> PeekIterator<'r, A, Self>; + /// An adaptation of an external iterator to the for-loop protocol of rust. /// /// # Example @@ -442,6 +461,12 @@ impl> IteratorUtil for T { FlatMapIterator{iter: self, f: f, subiter: None } } + // FIXME: #5898: should be called `peek` + #[inline] + fn peek_<'r>(self, f: &'r fn(&A)) -> PeekIterator<'r, A, T> { + PeekIterator{iter: self, f: f} + } + /// A shim implementing the `for` loop iteration protocol for iterator objects #[inline] fn advance(&mut self, f: &fn(A) -> bool) -> bool { @@ -1041,6 +1066,32 @@ impl<'self, A, T: Iterator, B, U: Iterator> Iterator for } } +/// An iterator that calls a function with a reference to each +/// element before yielding it. +pub struct PeekIterator<'self, A, T> { + priv iter: T, + priv f: &'self fn(&A) +} + +impl<'self, A, T: Iterator> Iterator for PeekIterator<'self, A, T> { + #[inline] + fn next(&mut self) -> Option { + let next = self.iter.next(); + + match next { + Some(ref a) => (self.f)(a), + None => () + } + + next + } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + self.iter.size_hint() + } +} + /// An iterator which just modifies the contained state throughout iteration. pub struct UnfoldrIterator<'self, A, St> { priv f: &'self fn(&mut St) -> Option, @@ -1236,6 +1287,20 @@ mod tests { assert_eq!(i, ys.len()); } + #[test] + fn test_peek() { + let xs = [1u, 2, 3, 4]; + let mut n = 0; + + let ys = xs.iter() + .transform(|&x| x) + .peek_(|_| n += 1) + .collect::<~[uint]>(); + + assert_eq!(n, xs.len()); + assert_eq!(xs, ys.as_slice()); + } + #[test] fn test_unfoldr() { fn count(st: &mut uint) -> Option { From 641aec74076f8c5735a7d379753194f877866525 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Thu, 4 Jul 2013 22:13:26 -0400 Subject: [PATCH 85/93] remove some method resolve workarounds --- src/libextra/getopts.rs | 2 +- src/libextra/json.rs | 2 +- src/libextra/net/ip.rs | 2 +- src/libextra/net/url.rs | 2 +- src/libextra/par.rs | 4 +-- src/libextra/terminfo/parser/compiled.rs | 2 +- src/libextra/treemap.rs | 2 +- src/librustc/front/config.rs | 2 +- src/librustc/metadata/cstore.rs | 2 +- src/librustc/middle/borrowck/move_data.rs | 4 +-- src/librustc/middle/check_const.rs | 2 +- src/librustc/middle/check_match.rs | 8 +++--- src/librustc/middle/dataflow.rs | 8 +++--- src/librustc/middle/kind.rs | 6 ++--- src/librustc/middle/lint.rs | 4 +-- src/librustc/middle/moves.rs | 4 +-- src/librustc/middle/privacy.rs | 20 +++++++------- src/librustc/middle/region.rs | 6 ++--- src/librustc/middle/trans/_match.rs | 10 +++---- src/librustc/middle/trans/adt.rs | 2 +- src/librustc/middle/trans/common.rs | 2 +- src/librustc/middle/trans/consts.rs | 2 +- src/librustc/middle/trans/expr.rs | 4 +-- src/librustc/middle/trans/monomorphize.rs | 2 +- src/librustc/middle/ty.rs | 12 ++++----- src/librustc/middle/typeck/astconv.rs | 2 +- src/librustc/middle/typeck/check/method.rs | 12 ++++----- src/librustc/middle/typeck/check/vtable.rs | 2 +- src/librustc/middle/typeck/collect.rs | 2 +- src/librustc/middle/typeck/infer/lattice.rs | 2 +- src/librustc/middle/typeck/infer/lub.rs | 2 +- .../typeck/infer/region_inference/mod.rs | 2 +- src/librustc/middle/typeck/infer/sub.rs | 2 +- src/librustc/rustc.rs | 4 +-- src/librustdoc/attr_parser.rs | 2 +- src/librustdoc/rustdoc.rs | 2 +- src/librusti/rusti.rs | 2 +- src/librustpkg/tests.rs | 14 +++++----- src/librustpkg/util.rs | 2 +- src/libstd/iterator.rs | 26 +++++++++---------- src/libstd/run.rs | 2 +- src/libstd/str.rs | 2 +- src/libstd/task/local_data_priv.rs | 4 +-- src/libstd/vec.rs | 4 +-- src/libsyntax/attr.rs | 2 +- src/libsyntax/ext/expand.rs | 2 +- src/libsyntax/parse/parser.rs | 2 +- src/test/bench/core-std.rs | 2 +- src/test/bench/graph500-bfs.rs | 6 ++--- src/test/run-pass/block-arg.rs | 12 ++++----- src/test/run-pass/test-ignore-cfg.rs | 4 +-- 51 files changed, 118 insertions(+), 118 deletions(-) diff --git a/src/libextra/getopts.rs b/src/libextra/getopts.rs index 1a494f36c646..c481fb8f5440 100644 --- a/src/libextra/getopts.rs +++ b/src/libextra/getopts.rs @@ -176,7 +176,7 @@ fn name_str(nm: &Name) -> ~str { } fn find_opt(opts: &[Opt], nm: Name) -> Option { - opts.iter().position_(|opt| opt.name == nm) + opts.iter().position(|opt| opt.name == nm) } /** diff --git a/src/libextra/json.rs b/src/libextra/json.rs index 71d99479693f..b9b2099d7c22 100644 --- a/src/libextra/json.rs +++ b/src/libextra/json.rs @@ -950,7 +950,7 @@ impl serialize::Decoder for Decoder { } ref json => fail!("invalid variant: %?", *json), }; - let idx = match names.iter().position_(|n| str::eq_slice(*n, name)) { + let idx = match names.iter().position(|n| str::eq_slice(*n, name)) { Some(idx) => idx, None => fail!("Unknown variant name: %?", name), }; diff --git a/src/libextra/net/ip.rs b/src/libextra/net/ip.rs index bf58f81ef0e3..6876b3510b6c 100644 --- a/src/libextra/net/ip.rs +++ b/src/libextra/net/ip.rs @@ -203,7 +203,7 @@ pub mod v4 { }).collect(); if parts.len() != 4 { Err(fmt!("'%s' doesn't have 4 parts", ip)) - } else if parts.iter().any_(|x| *x == 256u) { + } else if parts.iter().any(|x| *x == 256u) { Err(fmt!("invalid octal in addr '%s'", ip)) } else { Ok(Ipv4Rep { diff --git a/src/libextra/net/url.rs b/src/libextra/net/url.rs index 4ed8761cc11b..307f75dc98be 100644 --- a/src/libextra/net/url.rs +++ b/src/libextra/net/url.rs @@ -522,7 +522,7 @@ fn get_authority(rawurl: &str) -> let host_is_end_plus_one: &fn() -> bool = || { let xs = ['?', '#', '/']; end+1 == len - && !xs.iter().any_(|x| *x == (rawurl[end] as char)) + && !xs.iter().any(|x| *x == (rawurl[end] as char)) }; // finish up diff --git a/src/libextra/par.rs b/src/libextra/par.rs index d56f7b32ae7d..d737698cfe2c 100644 --- a/src/libextra/par.rs +++ b/src/libextra/par.rs @@ -136,8 +136,8 @@ pub fn any( fn_factory: &fn() -> ~fn(&A) -> bool) -> bool { let mapped = map_slices(xs, || { let f = fn_factory(); - let result: ~fn(uint, &[A]) -> bool = |_, slice| slice.iter().any_(f); + let result: ~fn(uint, &[A]) -> bool = |_, slice| slice.iter().any(f); result }); - mapped.iter().any_(|&x| x) + mapped.iter().any(|&x| x) } diff --git a/src/libextra/terminfo/parser/compiled.rs b/src/libextra/terminfo/parser/compiled.rs index e16297e38717..e56b3b6bcf4c 100644 --- a/src/libextra/terminfo/parser/compiled.rs +++ b/src/libextra/terminfo/parser/compiled.rs @@ -294,7 +294,7 @@ pub fn parse(file: @Reader, longnames: bool) -> Result<~TermInfo, ~str> { // Find the offset of the NUL we want to go to let nulpos = string_table.slice(offset as uint, string_table_bytes as uint) - .iter().position_(|&b| b == 0); + .iter().position(|&b| b == 0); match nulpos { Some(len) => { string_map.insert(name.to_owned(), diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index 17970f158dd2..a5f7479d41a0 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -844,7 +844,7 @@ mod test_treemap { for 90.times { let k = rng.gen(); let v = rng.gen(); - if !ctrl.iter().any_(|x| x == &(k, v)) { + if !ctrl.iter().any(|x| x == &(k, v)) { assert!(map.insert(k, v)); ctrl.push((k, v)); check_structure(&map); diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs index df829d5e2096..0d4d96b3b2b3 100644 --- a/src/librustc/front/config.rs +++ b/src/librustc/front/config.rs @@ -194,7 +194,7 @@ pub fn metas_in_cfg(cfg: &[@ast::meta_item], if cfg_metas.iter().all(|c| c.is_empty()) { return true; } - cfg_metas.iter().any_(|cfg_meta| { + cfg_metas.iter().any(|cfg_meta| { cfg_meta.iter().all(|cfg_mi| { match cfg_mi.node { ast::meta_list(s, ref it) if "not" == s diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index 3413cd341ba4..bb1834dc5c8f 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -102,7 +102,7 @@ pub fn get_used_crate_files(cstore: &CStore) -> ~[Path] { pub fn add_used_library(cstore: &mut CStore, lib: @str) -> bool { assert!(!lib.is_empty()); - if cstore.used_libraries.iter().any_(|x| x == &lib) { return false; } + if cstore.used_libraries.iter().any(|x| x == &lib) { return false; } cstore.used_libraries.push(lib); true } diff --git a/src/librustc/middle/borrowck/move_data.rs b/src/librustc/middle/borrowck/move_data.rs index 97fd6ca5cc43..73adade7a5d7 100644 --- a/src/librustc/middle/borrowck/move_data.rs +++ b/src/librustc/middle/borrowck/move_data.rs @@ -506,7 +506,7 @@ impl FlowedMoveData { for self.dfcx_moves.each_bit_on_entry_frozen(id) |index| { let move = &self.move_data.moves[index]; let moved_path = move.path; - if base_indices.iter().any_(|x| x == &moved_path) { + if base_indices.iter().any(|x| x == &moved_path) { // Scenario 1 or 2: `loan_path` or some base path of // `loan_path` was moved. if !f(move, self.move_data.path(moved_path).loan_path) { @@ -535,7 +535,7 @@ impl FlowedMoveData { -> bool { //! True if `id` is the id of the LHS of an assignment - self.move_data.assignee_ids.iter().any_(|x| x == &id) + self.move_data.assignee_ids.iter().any(|x| x == &id) } pub fn each_assignment_of(&self, diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 7113244c7f6c..26a03b362e35 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -224,7 +224,7 @@ pub fn check_item_recursion(sess: Session, (visitor.visit_item)(it, (env, visitor)); fn visit_item(it: @item, (env, v): (env, visit::vt)) { - if env.idstack.iter().any_(|x| x == &(it.id)) { + if env.idstack.iter().any(|x| x == &(it.id)) { env.sess.span_fatal(env.root_it.span, "recursive constant"); } env.idstack.push(it.id); diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 740499bbf25e..0baeb8ce57c6 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -371,7 +371,7 @@ pub fn missing_ctor(cx: &MatchCheckCtxt, let variants = ty::enum_variants(cx.tcx, eid); if found.len() != (*variants).len() { for (*variants).iter().advance |v| { - if !found.iter().any_(|x| x == &(variant(v.id))) { + if !found.iter().any(|x| x == &(variant(v.id))) { return Some(variant(v.id)); } } @@ -805,13 +805,13 @@ pub fn is_refutable(cx: &MatchCheckCtxt, pat: &pat) -> bool { } pat_lit(_) | pat_range(_, _) => { true } pat_struct(_, ref fields, _) => { - fields.iter().any_(|f| is_refutable(cx, f.pat)) + fields.iter().any(|f| is_refutable(cx, f.pat)) } pat_tup(ref elts) => { - elts.iter().any_(|elt| is_refutable(cx, *elt)) + elts.iter().any(|elt| is_refutable(cx, *elt)) } pat_enum(_, Some(ref args)) => { - args.iter().any_(|a| is_refutable(cx, *a)) + args.iter().any(|a| is_refutable(cx, *a)) } pat_enum(_,_) => { false } pat_vec(*) => { true } diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index ac18a9b76cf9..e054b84984d1 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -341,14 +341,14 @@ impl DataFlowContext { let entry_str = bits_to_str(on_entry); let gens = self.gens.slice(start, end); - let gens_str = if gens.iter().any_(|&u| u != 0) { + let gens_str = if gens.iter().any(|&u| u != 0) { fmt!(" gen: %s", bits_to_str(gens)) } else { ~"" }; let kills = self.kills.slice(start, end); - let kills_str = if kills.iter().any_(|&u| u != 0) { + let kills_str = if kills.iter().any(|&u| u != 0) { fmt!(" kill: %s", bits_to_str(kills)) } else { ~"" @@ -643,7 +643,7 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> { self.walk_opt_expr(o_e, in_out, loop_scopes); // is this a return from a `for`-loop closure? - match loop_scopes.iter().position_(|s| s.loop_kind == ForLoop) { + match loop_scopes.iter().position(|s| s.loop_kind == ForLoop) { Some(i) => { // if so, add the in_out bits to the state // upon exit. Remember that we cannot count @@ -916,7 +916,7 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> { Some(_) => { match self.tcx().def_map.find(&expr.id) { Some(&ast::def_label(loop_id)) => { - match loop_scopes.iter().position_(|l| l.loop_id == loop_id) { + match loop_scopes.iter().position(|l| l.loop_id == loop_id) { Some(i) => i, None => { self.tcx().sess.span_bug( diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index 335a54a97535..a9454d1b2309 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -536,7 +536,7 @@ pub fn check_cast_for_escaping_regions( // Check, based on the region associated with the trait, whether it can // possibly escape the enclosing fn item (note that all type parameters // must have been declared on the enclosing fn item). - if target_regions.iter().any_(|r| is_re_scope(*r)) { + if target_regions.iter().any(|r| is_re_scope(*r)) { return; /* case (1) */ } @@ -551,7 +551,7 @@ pub fn check_cast_for_escaping_regions( |_r| { // FIXME(#5723) --- turn this check on once &Objects are usable // - // if !target_regions.iter().any_(|t_r| is_subregion_of(cx, *t_r, r)) { + // if !target_regions.iter().any(|t_r| is_subregion_of(cx, *t_r, r)) { // cx.tcx.sess.span_err( // source.span, // fmt!("source contains borrowed pointer with lifetime \ @@ -565,7 +565,7 @@ pub fn check_cast_for_escaping_regions( |ty| { match ty::get(ty).sty { ty::ty_param(source_param) => { - if target_params.iter().any_(|x| x == &source_param) { + if target_params.iter().any(|x| x == &source_param) { /* case (2) */ } else { check_durable(cx.tcx, ty, source.span); /* case (3) */ diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 0dce9c69bfdb..0fc19ffd78e5 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -898,7 +898,7 @@ fn check_item_non_uppercase_statics(cx: &Context, it: &ast::item) { // check for lowercase letters rather than non-uppercase // ones (some scripts don't have a concept of // upper/lowercase) - if s.iter().any_(|c| c.is_lowercase()) { + if s.iter().any(|c| c.is_lowercase()) { cx.span_lint(non_uppercase_statics, it.span, "static constant should have an uppercase identifier"); } @@ -1038,7 +1038,7 @@ fn lint_missing_doc() -> visit::vt<@mut Context> { // If we have doc(hidden), nothing to do if cx.doc_hidden { return } // If we're documented, nothing to do - if attrs.iter().any_(|a| a.node.is_sugared_doc) { return } + if attrs.iter().any(|a| a.node.is_sugared_doc) { return } // otherwise, warn! cx.span_lint(missing_doc, sp, msg); diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs index c7d338b1976a..f3d4abcdf310 100644 --- a/src/librustc/middle/moves.rs +++ b/src/librustc/middle/moves.rs @@ -390,8 +390,8 @@ impl VisitContext { // any fields which (1) were not explicitly // specified and (2) have a type that // moves-by-default: - let consume_with = with_fields.iter().any_(|tf| { - !fields.iter().any_(|f| f.node.ident == tf.ident) && + let consume_with = with_fields.iter().any(|tf| { + !fields.iter().any(|f| f.node.ident == tf.ident) && ty::type_moves_by_default(self.tcx, tf.mt.ty) }); diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index dd6b5615c3f3..8a2b13419153 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -259,7 +259,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, method_id.node); if is_private && (container_id.crate != local_crate || - !privileged_items.iter().any_(|x| x == &(container_id.node))) { + !privileged_items.iter().any(|x| x == &(container_id.node))) { tcx.sess.span_err(span, fmt!("method `%s` is private", token::ident_to_str(name))); @@ -287,7 +287,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, def_fn(def_id, _) => { if def_id.crate == local_crate { if local_item_is_private(span, def_id.node) && - !privileged_items.iter().any_(|x| x == &def_id.node) { + !privileged_items.iter().any(|x| x == &def_id.node) { tcx.sess.span_err(span, fmt!("function `%s` is private", token::ident_to_str(path.idents.last()))); @@ -332,7 +332,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, provided(method) if method.vis == private && !privileged_items.iter() - .any_(|x| x == &(trait_id.node)) => { + .any(|x| x == &(trait_id.node)) => { tcx.sess.span_err(span, fmt!("method `%s` is private", token::ident_to_str(&method @@ -417,7 +417,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, base))).sty { ty_struct(id, _) if id.crate != local_crate || !privileged_items.iter() - .any_(|x| x == &(id.node)) => { + .any(|x| x == &(id.node)) => { debug!("(privacy checking) checking field access"); check_field(expr.span, id, ident); } @@ -430,7 +430,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, base))).sty { ty_struct(id, _) if id.crate != local_crate || - !privileged_items.iter().any_(|x| x == &(id.node)) => { + !privileged_items.iter().any(|x| x == &(id.node)) => { match method_map.find(&expr.id) { None => { tcx.sess.span_bug(expr.span, @@ -456,7 +456,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, match ty::get(ty::expr_ty(tcx, expr)).sty { ty_struct(id, _) => { if id.crate != local_crate || - !privileged_items.iter().any_(|x| x == &(id.node)) { + !privileged_items.iter().any(|x| x == &(id.node)) { for (*fields).iter().advance |field| { debug!("(privacy checking) checking \ field in struct literal"); @@ -467,7 +467,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, } ty_enum(id, _) => { if id.crate != local_crate || - !privileged_items.iter().any_(|x| x == &(id.node)) { + !privileged_items.iter().any(|x| x == &(id.node)) { match tcx.def_map.get_copy(&expr.id) { def_variant(_, variant_id) => { for (*fields).iter().advance |field| { @@ -504,7 +504,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, match ty::get(ty::expr_ty(tcx, operand)).sty { ty_enum(id, _) => { if id.crate != local_crate || - !privileged_items.iter().any_(|x| x == &(id.node)) { + !privileged_items.iter().any(|x| x == &(id.node)) { check_variant(expr.span, id); } } @@ -522,7 +522,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, match ty::get(ty::pat_ty(tcx, pattern)).sty { ty_struct(id, _) => { if id.crate != local_crate || - !privileged_items.iter().any_(|x| x == &(id.node)) { + !privileged_items.iter().any(|x| x == &(id.node)) { for fields.iter().advance |field| { debug!("(privacy checking) checking \ struct pattern"); @@ -533,7 +533,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, } ty_enum(enum_id, _) => { if enum_id.crate != local_crate || - !privileged_items.iter().any_(|x| x == &enum_id.node) { + !privileged_items.iter().any(|x| x == &enum_id.node) { match tcx.def_map.find(&pattern.id) { Some(&def_variant(_, variant_id)) => { for fields.iter().advance |field| { diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index b1b2a0083acc..e1c43121ec82 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -78,7 +78,7 @@ impl RegionMaps { pub fn relate_free_regions(&mut self, sub: FreeRegion, sup: FreeRegion) { match self.free_region_map.find_mut(&sub) { Some(sups) => { - if !sups.iter().any_(|x| x == &sup) { + if !sups.iter().any(|x| x == &sup) { sups.push(sup); } return; @@ -202,7 +202,7 @@ impl RegionMaps { return true; } - if !queue.iter().any_(|x| x == parent) { + if !queue.iter().any(|x| x == parent) { queue.push(*parent); } } @@ -612,7 +612,7 @@ impl DetermineRpCtxt { ambient_variance: self.ambient_variance, id: self.item_id }; - if !vec.iter().any_(|x| x == &dep) { vec.push(dep); } + if !vec.iter().any(|x| x == &dep) { vec.push(dep); } } // Determines whether a reference to a region that appears in the diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 3e828a891d49..511e4fdd864c 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -796,7 +796,7 @@ pub fn enter_region<'r>(bcx: block, pub fn get_options(bcx: block, m: &[@Match], col: uint) -> ~[Opt] { let ccx = bcx.ccx(); fn add_to_set(tcx: ty::ctxt, set: &mut ~[Opt], val: Opt) { - if set.iter().any_(|l| opt_eq(tcx, l, &val)) {return;} + if set.iter().any(|l| opt_eq(tcx, l, &val)) {return;} set.push(val); } @@ -963,7 +963,7 @@ pub fn collect_record_or_struct_fields(bcx: block, fn extend(idents: &mut ~[ast::ident], field_pats: &[ast::field_pat]) { for field_pats.iter().advance |field_pat| { let field_ident = field_pat.ident; - if !idents.iter().any_(|x| *x == field_ident) { + if !idents.iter().any(|x| *x == field_ident) { idents.push(field_ident); } } @@ -974,7 +974,7 @@ pub fn pats_require_rooting(bcx: block, m: &[@Match], col: uint) -> bool { - do m.iter().any_ |br| { + do m.iter().any |br| { let pat_id = br.pats[col].id; let key = root_map_key {id: pat_id, derefs: 0u }; bcx.ccx().maps.root_map.contains_key(&key) @@ -1003,7 +1003,7 @@ pub fn root_pats_as_necessary(mut bcx: block, // matches may be wildcards like _ or identifiers). macro_rules! any_pat ( ($m:expr, $pattern:pat) => ( - do ($m).iter().any_ |br| { + do ($m).iter().any |br| { match br.pats[col].node { $pattern => true, _ => false @@ -1029,7 +1029,7 @@ pub fn any_tup_pat(m: &[@Match], col: uint) -> bool { } pub fn any_tuple_struct_pat(bcx: block, m: &[@Match], col: uint) -> bool { - do m.iter().any_ |br| { + do m.iter().any |br| { let pat = br.pats[col]; match pat.node { ast::pat_enum(_, Some(_)) => { diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index 4755f7629511..dc8f6b1d05b5 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -147,7 +147,7 @@ fn represent_type_uncached(cx: &mut CrateContext, t: ty::t) -> Repr { mk_struct(cx, self.tys, false).size == 0 } fn find_ptr(&self) -> Option { - self.tys.iter().position_(|&ty| mono_data_classify(ty) == MonoNonNull) + self.tys.iter().position(|&ty| mono_data_classify(ty) == MonoNonNull) } } diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 19c94d95c4f9..fa994ccaa651 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -413,7 +413,7 @@ pub fn add_clean_free(cx: block, ptr: ValueRef, heap: heap) { // drop glue checks whether it is zero. pub fn revoke_clean(cx: block, val: ValueRef) { do in_scope_cx(cx, None) |scope_info| { - let cleanup_pos = scope_info.cleanups.iter().position_( + let cleanup_pos = scope_info.cleanups.iter().position( |cu| match *cu { clean_temp(v, _, _) if v == val => true, _ => false diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index bbec78880fe2..9044ef570032 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -91,7 +91,7 @@ pub fn const_vec(cx: @mut CrateContext, e: &ast::expr, es: &[@ast::expr]) let sz = llvm::LLVMConstMul(C_uint(cx, es.len()), unit_sz); let vs = es.map(|e| const_expr(cx, *e)); // If the vector contains enums, an LLVM array won't work. - let v = if vs.iter().any_(|vi| val_ty(*vi) != llunitty) { + let v = if vs.iter().any(|vi| val_ty(*vi) != llunitty) { C_struct(vs) } else { C_array(llunitty, vs) diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 9c831db514a5..d1dde628dd00 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -1147,7 +1147,7 @@ fn trans_rec_or_struct(bcx: block, let mut need_base = vec::from_elem(field_tys.len(), true); let numbered_fields = do fields.map |field| { - let opt_pos = field_tys.iter().position_(|field_ty| field_ty.ident == field.node.ident); + let opt_pos = field_tys.iter().position(|field_ty| field_ty.ident == field.node.ident); match opt_pos { Some(i) => { need_base[i] = false; @@ -1171,7 +1171,7 @@ fn trans_rec_or_struct(bcx: block, fields: leftovers }) } None => { - if need_base.iter().any_(|b| *b) { + if need_base.iter().any(|b| *b) { tcx.sess.span_bug(expr_span, "missing fields and no base expr") } None diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index bfe8c012777b..bbcf68c386de 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -84,7 +84,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, let hash_id = make_mono_id(ccx, fn_id, impl_did_opt, &*psubsts, Some(param_uses)); - if hash_id.params.iter().any_( + if hash_id.params.iter().any( |p| match *p { mono_precise(_, _) => false, _ => true }) { must_cast = true; } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 129208a9aa37..dce899010c76 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1485,8 +1485,8 @@ pub fn type_needs_subst(ty: t) -> bool { } pub fn trait_ref_contains_error(tref: &ty::TraitRef) -> bool { - tref.substs.self_ty.iter().any_(|&t| type_is_error(t)) || - tref.substs.tps.iter().any_(|&t| type_is_error(t)) + tref.substs.self_ty.iter().any(|&t| type_is_error(t)) || + tref.substs.tps.iter().any(|&t| type_is_error(t)) } pub fn type_is_ty_var(ty: t) -> bool { @@ -2342,13 +2342,13 @@ pub fn is_instantiable(cx: ctxt, r_ty: t) -> bool { ty_struct(did, ref substs) => { seen.push(did); let fields = struct_fields(cx, did, substs); - let r = fields.iter().any_(|f| type_requires(cx, seen, r_ty, f.mt.ty)); + let r = fields.iter().any(|f| type_requires(cx, seen, r_ty, f.mt.ty)); seen.pop(); r } ty_tup(ref ts) => { - ts.iter().any_(|t| type_requires(cx, seen, r_ty, *t)) + ts.iter().any(|t| type_requires(cx, seen, r_ty, *t)) } ty_enum(ref did, _) if seen.contains(did) => { @@ -2359,7 +2359,7 @@ pub fn is_instantiable(cx: ctxt, r_ty: t) -> bool { seen.push(did); let vs = enum_variants(cx, did); let r = !vs.is_empty() && do vs.iter().all |variant| { - do variant.args.iter().any_ |aty| { + do variant.args.iter().any |aty| { let sty = subst(cx, substs, *aty); type_requires(cx, seen, r_ty, sty) } @@ -3241,7 +3241,7 @@ pub fn field_idx_strict(tcx: ty::ctxt, id: ast::ident, fields: &[field]) } pub fn method_idx(id: ast::ident, meths: &[@Method]) -> Option { - meths.iter().position_(|m| m.ident == id) + meths.iter().position(|m| m.ident == id) } /// Returns a vector containing the indices of all type parameters that appear diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 9442eb0b8386..d8185022e416 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -553,7 +553,7 @@ pub fn bound_lifetimes( let special_idents = [special_idents::statik, special_idents::self_]; let mut bound_lifetime_names = opt_vec::Empty; ast_lifetimes.map_to_vec(|ast_lifetime| { - if special_idents.iter().any_(|&i| i == ast_lifetime.ident) { + if special_idents.iter().any(|&i| i == ast_lifetime.ident) { this.tcx().sess.span_err( ast_lifetime.span, fmt!("illegal lifetime parameter name: `%s`", diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index ee61399113a4..04c83f40f6cf 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -253,7 +253,7 @@ impl<'self> LookupContext<'self> { ty_enum(did, _) => { // Watch out for newtype'd enums like "enum t = @T". // See discussion in typeck::check::do_autoderef(). - if enum_dids.iter().any_(|x| x == &did) { + if enum_dids.iter().any(|x| x == &did) { return None; } enum_dids.push(did); @@ -368,7 +368,7 @@ impl<'self> LookupContext<'self> { let trait_methods = ty::trait_methods(tcx, bound_trait_ref.def_id); let pos = { - match trait_methods.iter().position_(|m| { + match trait_methods.iter().position(|m| { m.explicit_self != ast::sty_static && m.ident == self.m_name }) { @@ -412,7 +412,7 @@ impl<'self> LookupContext<'self> { let tcx = self.tcx(); let ms = ty::trait_methods(tcx, did); - let index = match ms.iter().position_(|m| m.ident == self.m_name) { + let index = match ms.iter().position(|m| m.ident == self.m_name) { Some(i) => i, None => { return; } // no method with the right name }; @@ -466,7 +466,7 @@ impl<'self> LookupContext<'self> { // First, try self methods let mut method_info: Option = None; let methods = ty::trait_methods(tcx, did); - match methods.iter().position_(|m| m.ident == self.m_name) { + match methods.iter().position(|m| m.ident == self.m_name) { Some(i) => { method_info = Some(MethodInfo { method_ty: methods[i], @@ -482,7 +482,7 @@ impl<'self> LookupContext<'self> { for ty::trait_supertraits(tcx, did).iter().advance |trait_ref| { let supertrait_methods = ty::trait_methods(tcx, trait_ref.def_id); - match supertrait_methods.iter().position_(|m| m.ident == self.m_name) { + match supertrait_methods.iter().position(|m| m.ident == self.m_name) { Some(i) => { method_info = Some(MethodInfo { method_ty: supertrait_methods[i], @@ -538,7 +538,7 @@ impl<'self> LookupContext<'self> { impl_info.methods.map(|m| m.ident).repr(self.tcx())); let idx = { - match impl_info.methods.iter().position_(|m| m.ident == self.m_name) { + match impl_info.methods.iter().position(|m| m.ident == self.m_name) { Some(idx) => idx, None => { return; } // No method with the right name. } diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs index d90863344396..7cc328674143 100644 --- a/src/librustc/middle/typeck/check/vtable.rs +++ b/src/librustc/middle/typeck/check/vtable.rs @@ -67,7 +67,7 @@ impl VtableContext { } fn has_trait_bounds(type_param_defs: &[ty::TypeParameterDef]) -> bool { - type_param_defs.iter().any_( + type_param_defs.iter().any( |type_param_def| !type_param_def.bounds.trait_bounds.is_empty()) } diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index fb88f198231f..fb544335a723 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -391,7 +391,7 @@ pub fn ensure_supertraits(ccx: &CrateCtxt, generics, self_ty); // FIXME(#5527) Could have same trait multiple times - if ty_trait_refs.iter().any_(|other_trait| other_trait.def_id == trait_ref.def_id) { + if ty_trait_refs.iter().any(|other_trait| other_trait.def_id == trait_ref.def_id) { // This means a trait inherited from the same supertrait more // than once. tcx.sess.span_err(sp, "Duplicate supertrait in trait declaration"); diff --git a/src/librustc/middle/typeck/infer/lattice.rs b/src/librustc/middle/typeck/infer/lattice.rs index b1a6aefd1794..90a316c78f96 100644 --- a/src/librustc/middle/typeck/infer/lattice.rs +++ b/src/librustc/middle/typeck/infer/lattice.rs @@ -540,7 +540,7 @@ pub fn var_ids(this: &T, isr: isr_alist) -> ~[RegionVid] { pub fn is_var_in_set(new_vars: &[RegionVid], r: ty::Region) -> bool { match r { - ty::re_infer(ty::ReVar(ref v)) => new_vars.iter().any_(|x| x == v), + ty::re_infer(ty::ReVar(ref v)) => new_vars.iter().any(|x| x == v), _ => false } } diff --git a/src/librustc/middle/typeck/infer/lub.rs b/src/librustc/middle/typeck/infer/lub.rs index 3f23fd6e7096..96d18976358e 100644 --- a/src/librustc/middle/typeck/infer/lub.rs +++ b/src/librustc/middle/typeck/infer/lub.rs @@ -184,7 +184,7 @@ impl Combine for Lub { // with. for list::each(a_isr) |pair| { let (a_br, a_r) = *pair; - if tainted.iter().any_(|x| x == &a_r) { + if tainted.iter().any(|x| x == &a_r) { debug!("generalize_region(r0=%?): \ replacing with %?, tainted=%?", r0, a_br, tainted); diff --git a/src/librustc/middle/typeck/infer/region_inference/mod.rs b/src/librustc/middle/typeck/infer/region_inference/mod.rs index 7bf4d07b7230..50290ba752e7 100644 --- a/src/librustc/middle/typeck/infer/region_inference/mod.rs +++ b/src/librustc/middle/typeck/infer/region_inference/mod.rs @@ -454,7 +454,7 @@ impl RegionVarBindings { { let mut result_set = result_set; if r == r1 { // Clearly, this is potentially inefficient. - if !result_set.iter().any_(|x| *x == r2) { + if !result_set.iter().any(|x| *x == r2) { result_set.push(r2); } } diff --git a/src/librustc/middle/typeck/infer/sub.rs b/src/librustc/middle/typeck/infer/sub.rs index cfb33732459f..7e418c0061d3 100644 --- a/src/librustc/middle/typeck/infer/sub.rs +++ b/src/librustc/middle/typeck/infer/sub.rs @@ -199,7 +199,7 @@ impl Combine for Sub { // or new variables: match *tainted_region { ty::re_infer(ty::ReVar(ref vid)) => { - if new_vars.iter().any_(|x| x == vid) { loop; } + if new_vars.iter().any(|x| x == vid) { loop; } } _ => { if *tainted_region == skol { loop; } diff --git a/src/librustc/rustc.rs b/src/librustc/rustc.rs index 243ddb2a14b0..35375d025ebc 100644 --- a/src/librustc/rustc.rs +++ b/src/librustc/rustc.rs @@ -212,7 +212,7 @@ pub fn run_compiler(args: &~[~str], demitter: diagnostic::Emitter) { let lint_flags = vec::append(getopts::opt_strs(matches, "W"), getopts::opt_strs(matches, "warn")); - let show_lint_options = lint_flags.iter().any_(|x| x == &~"help") || + let show_lint_options = lint_flags.iter().any(|x| x == &~"help") || (opt_present(matches, "W") && lint_flags.is_empty()); if show_lint_options { @@ -221,7 +221,7 @@ pub fn run_compiler(args: &~[~str], demitter: diagnostic::Emitter) { } let r = getopts::opt_strs(matches, "Z"); - if r.iter().any_(|x| x == &~"help") { + if r.iter().any(|x| x == &~"help") { describe_debug_flags(); return; } diff --git a/src/librustdoc/attr_parser.rs b/src/librustdoc/attr_parser.rs index 0681cf867f13..e61f8d6d7433 100644 --- a/src/librustdoc/attr_parser.rs +++ b/src/librustdoc/attr_parser.rs @@ -57,7 +57,7 @@ pub fn parse_desc(attrs: ~[ast::attribute]) -> Option<~str> { pub fn parse_hidden(attrs: ~[ast::attribute]) -> bool { let r = doc_metas(attrs); - do r.iter().any_ |meta| { + do r.iter().any |meta| { match attr::get_meta_item_list(*meta) { Some(metas) => { let hiddens = attr::find_meta_items_by_name(metas, "hidden"); diff --git a/src/librustdoc/rustdoc.rs b/src/librustdoc/rustdoc.rs index 3659d24a254f..ccf014fb2383 100644 --- a/src/librustdoc/rustdoc.rs +++ b/src/librustdoc/rustdoc.rs @@ -64,7 +64,7 @@ pub mod util; pub fn main() { let args = os::args(); - if args.iter().any_(|x| "-h" == *x) || args.iter().any_(|x| "--help" == *x) { + if args.iter().any(|x| "-h" == *x) || args.iter().any(|x| "--help" == *x) { config::usage(); return; } diff --git a/src/librusti/rusti.rs b/src/librusti/rusti.rs index d9cd52201c0c..d7c03ce2ba76 100644 --- a/src/librusti/rusti.rs +++ b/src/librusti/rusti.rs @@ -381,7 +381,7 @@ fn run_cmd(repl: &mut Repl, _in: @io::Reader, _out: @io::Writer, let crate_path = Path(*crate); let crate_dir = crate_path.dirname(); repl.program.record_extern(fmt!("extern mod %s;", *crate)); - if !repl.lib_search_paths.iter().any_(|x| x == &crate_dir) { + if !repl.lib_search_paths.iter().any(|x| x == &crate_dir) { repl.lib_search_paths.push(crate_dir); } } diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs index 042879807ea9..251783577df8 100644 --- a/src/librustpkg/tests.rs +++ b/src/librustpkg/tests.rs @@ -626,14 +626,14 @@ fn install_remove() { command_line_test([~"install", ~"bar"], &dir); command_line_test([~"install", ~"quux"], &dir); let list_output = command_line_test_output([~"list"]); - assert!(list_output.iter().any_(|x| x == &~"foo")); - assert!(list_output.iter().any_(|x| x == &~"bar")); - assert!(list_output.iter().any_(|x| x == &~"quux")); + assert!(list_output.iter().any(|x| x == &~"foo")); + assert!(list_output.iter().any(|x| x == &~"bar")); + assert!(list_output.iter().any(|x| x == &~"quux")); command_line_test([~"remove", ~"foo"], &dir); let list_output = command_line_test_output([~"list"]); - assert!(!list_output.iter().any_(|x| x == &~"foo")); - assert!(list_output.iter().any_(|x| x == &~"bar")); - assert!(list_output.iter().any_(|x| x == &~"quux")); + assert!(!list_output.iter().any(|x| x == &~"foo")); + assert!(list_output.iter().any(|x| x == &~"bar")); + assert!(list_output.iter().any(|x| x == &~"quux")); } #[test] @@ -699,7 +699,7 @@ fn test_versions() { command_line_test([~"install", ~"foo#0.1"], &workspace); let output = command_line_test_output([~"list"]); // make sure output includes versions - assert!(!output.iter().any_(|x| x == &~"foo#0.2")); + assert!(!output.iter().any(|x| x == &~"foo#0.2")); } #[test] diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index 8a57cd4b25c0..900ef4896ca1 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -55,7 +55,7 @@ pub fn root() -> Path { } pub fn is_cmd(cmd: &str) -> bool { - COMMANDS.iter().any_(|&c| c == cmd) + COMMANDS.iter().any(|&c| c == cmd) } struct ListenerFn { diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index b164bcbd28b3..8094b2387495 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -338,16 +338,16 @@ pub trait IteratorUtil { /// ~~~ {.rust} /// let a = [1, 2, 3, 4, 5]; /// let mut it = a.iter(); - /// assert!(it.any_(|&x| *x == 3)); - /// assert!(!it.any_(|&x| *x == 3)); + /// assert!(it.any(|&x| *x == 3)); + /// assert!(!it.any(|&x| *x == 3)); /// ~~~ - fn any_(&mut self, f: &fn(A) -> bool) -> bool; + fn any(&mut self, f: &fn(A) -> bool) -> bool; /// Return the first element satisfying the specified predicate fn find_(&mut self, predicate: &fn(&A) -> bool) -> Option; /// Return the index of the first element satisfying the specified predicate - fn position_(&mut self, predicate: &fn(A) -> bool) -> Option; + fn position(&mut self, predicate: &fn(A) -> bool) -> Option; /// Count the number of elements satisfying the specified predicate fn count(&mut self, predicate: &fn(A) -> bool) -> uint; @@ -504,7 +504,7 @@ impl> IteratorUtil for T { } #[inline] - fn any_(&mut self, f: &fn(A) -> bool) -> bool { + fn any(&mut self, f: &fn(A) -> bool) -> bool { for self.advance |x| { if f(x) { return true; } } false } @@ -520,7 +520,7 @@ impl> IteratorUtil for T { /// Return the index of the first element satisfying the specified predicate #[inline] - fn position_(&mut self, predicate: &fn(A) -> bool) -> Option { + fn position(&mut self, predicate: &fn(A) -> bool) -> Option { let mut i = 0; for self.advance |x| { if predicate(x) { @@ -1368,10 +1368,10 @@ mod tests { #[test] fn test_any() { let v = ~&[1, 2, 3, 4, 5]; - assert!(v.iter().any_(|&x| x < 10)); - assert!(v.iter().any_(|&x| x.is_even())); - assert!(!v.iter().any_(|&x| x > 100)); - assert!(!v.slice(0, 0).iter().any_(|_| fail!())); + assert!(v.iter().any(|&x| x < 10)); + assert!(v.iter().any(|&x| x.is_even())); + assert!(!v.iter().any(|&x| x > 100)); + assert!(!v.slice(0, 0).iter().any(|_| fail!())); } #[test] @@ -1385,9 +1385,9 @@ mod tests { #[test] fn test_position() { let v = &[1, 3, 9, 27, 103, 14, 11]; - assert_eq!(v.iter().position_(|x| *x & 1 == 0).unwrap(), 5); - assert_eq!(v.iter().position_(|x| *x % 3 == 0).unwrap(), 1); - assert!(v.iter().position_(|x| *x % 12 == 0).is_none()); + assert_eq!(v.iter().position(|x| *x & 1 == 0).unwrap(), 5); + assert_eq!(v.iter().position(|x| *x % 3 == 0).unwrap(), 1); + assert!(v.iter().position(|x| *x % 12 == 0).is_none()); } #[test] diff --git a/src/libstd/run.rs b/src/libstd/run.rs index df15111a91f4..7e051b62171c 100644 --- a/src/libstd/run.rs +++ b/src/libstd/run.rs @@ -587,7 +587,7 @@ pub fn make_command_line(prog: &str, args: &[~str]) -> ~str { return cmd; fn append_arg(cmd: &mut ~str, arg: &str) { - let quote = arg.iter().any_(|c| c == ' ' || c == '\t'); + let quote = arg.iter().any(|c| c == ' ' || c == '\t'); if quote { cmd.push_char('"'); } diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 564c58f7097e..bdd9bebf158d 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -279,7 +279,7 @@ impl CharEq for extern "Rust" fn(char) -> bool { impl<'self, C: CharEq> CharEq for &'self [C] { #[inline] fn matches(&self, c: char) -> bool { - self.iter().any_(|m| m.matches(c)) + self.iter().any(|m| m.matches(c)) } fn only_ascii(&self) -> bool { diff --git a/src/libstd/task/local_data_priv.rs b/src/libstd/task/local_data_priv.rs index 0956b76c970a..8dd96df45453 100644 --- a/src/libstd/task/local_data_priv.rs +++ b/src/libstd/task/local_data_priv.rs @@ -142,7 +142,7 @@ unsafe fn local_data_lookup( -> Option<(uint, *libc::c_void)> { let key_value = key_to_key_value(key); - let map_pos = (*map).iter().position_(|entry| + let map_pos = (*map).iter().position(|entry| match *entry { Some((k,_,_)) => k == key_value, None => false @@ -215,7 +215,7 @@ pub unsafe fn local_set( } None => { // Find an empty slot. If not, grow the vector. - match (*map).iter().position_(|x| x.is_none()) { + match (*map).iter().position(|x| x.is_none()) { Some(empty_index) => { map[empty_index] = new_entry; } None => { map.push(new_entry); } } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index effbc008b6ac..84e4358a4960 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -191,7 +191,7 @@ impl<'self, T> Iterator<&'self [T]> for VecSplitIterator<'self, T> { return Some(self.v); } - match self.v.iter().position_(|x| (self.pred)(x)) { + match self.v.iter().position(|x| (self.pred)(x)) { None => { self.finished = true; Some(self.v) @@ -1010,7 +1010,7 @@ impl<'self,T:Eq> ImmutableEqVector for &'self [T] { /// Find the first index containing a matching value #[inline] fn position_elem(&self, x: &T) -> Option { - self.iter().position_(|y| *x == *y) + self.iter().position(|y| *x == *y) } /// Find the last index containing a matching value diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index d04d96b2481d..e4532c476d75 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -192,7 +192,7 @@ fn eq(a: @ast::meta_item, b: @ast::meta_item) -> bool { ast::meta_list(ref nb, ref misb) => { if na != nb { return false; } for misa.iter().advance |mi| { - if !misb.iter().any_(|x| x == mi) { return false; } + if !misb.iter().any(|x| x == mi) { return false; } } true } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 940bd5ef61c1..71e0d49493b8 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -198,7 +198,7 @@ pub fn expand_item(extsbox: @mut SyntaxEnv, // does this attribute list contain "macro_escape" ? pub fn contains_macro_escape (attrs: &[ast::attribute]) -> bool { - attrs.iter().any_(|attr| "macro_escape" == attr::get_attr_name(attr)) + attrs.iter().any(|attr| "macro_escape" == attr::get_attr_name(attr)) } // Support for item-position macro invocations, exactly the same diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 2f79f60fb608..c43b350abdbf 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3914,7 +3914,7 @@ impl Parser { }; let full_path = full_path.normalize(); - let maybe_i = do self.sess.included_mod_stack.iter().position_ |&p| { p == full_path }; + let maybe_i = do self.sess.included_mod_stack.iter().position |&p| { p == full_path }; match maybe_i { Some(i) => { let stack = &self.sess.included_mod_stack; diff --git a/src/test/bench/core-std.rs b/src/test/bench/core-std.rs index c4d89a698c1a..867be38545cd 100644 --- a/src/test/bench/core-std.rs +++ b/src/test/bench/core-std.rs @@ -44,7 +44,7 @@ fn maybe_run_test(argv: &[~str], name: ~str, test: &fn()) { if os::getenv(~"RUST_BENCH").is_some() { run_test = true } else if argv.len() > 0 { - run_test = argv.iter().any_(|x| x == &~"all") || argv.iter().any_(|x| x == &name) + run_test = argv.iter().any(|x| x == &~"all") || argv.iter().any(|x| x == &name) } if !run_test { diff --git a/src/test/bench/graph500-bfs.rs b/src/test/bench/graph500-bfs.rs index d327b73c625e..47de9334be15 100644 --- a/src/test/bench/graph500-bfs.rs +++ b/src/test/bench/graph500-bfs.rs @@ -111,7 +111,7 @@ fn gen_search_keys(graph: &[~[node_id]], n: uint) -> ~[node_id] { while keys.len() < n { let k = r.gen_uint_range(0u, graph.len()); - if graph[k].len() > 0u && graph[k].iter().any_(|i| { + if graph[k].len() > 0u && graph[k].iter().any(|i| { *i != k as node_id }) { keys.insert(k as node_id); @@ -187,7 +187,7 @@ fn bfs2(graph: graph, key: node_id) -> bfs_result { } let mut i = 0; - while colors.iter().any_(is_gray) { + while colors.iter().any(is_gray) { // Do the BFS. info!("PBFS iteration %?", i); i += 1; @@ -402,7 +402,7 @@ fn validate(edges: ~[(node_id, node_id)], if *v == -1i64 || u == root { true } else { - edges.iter().any_(|x| x == &(u, *v)) || edges.iter().any_(|x| x == &(*v, u)) + edges.iter().any(|x| x == &(u, *v)) || edges.iter().any(|x| x == &(*v, u)) } }; result diff --git a/src/test/run-pass/block-arg.rs b/src/test/run-pass/block-arg.rs index 8ea2a88fa09a..466f2def290b 100644 --- a/src/test/run-pass/block-arg.rs +++ b/src/test/run-pass/block-arg.rs @@ -20,20 +20,20 @@ pub fn main() { } // Usable at all: - let mut any_negative = do v.iter().any_ |e| { e.is_negative() }; + let mut any_negative = do v.iter().any |e| { e.is_negative() }; assert!(any_negative); // Higher precedence than assignments: - any_negative = do v.iter().any_ |e| { e.is_negative() }; + any_negative = do v.iter().any |e| { e.is_negative() }; assert!(any_negative); // Higher precedence than unary operations: let abs_v = do v.iter().transform |e| { e.abs() }.collect::<~[float]>(); assert!(do abs_v.iter().all |e| { e.is_positive() }); - assert!(!do abs_v.iter().any_ |e| { e.is_negative() }); + assert!(!do abs_v.iter().any |e| { e.is_negative() }); // Usable in funny statement-like forms: - if !do v.iter().any_ |e| { e.is_positive() } { + if !do v.iter().any |e| { e.is_positive() } { assert!(false); } match do v.iter().all |e| { e.is_negative() } { @@ -41,7 +41,7 @@ pub fn main() { false => { } } match 3 { - _ if do v.iter().any_ |e| { e.is_negative() } => { + _ if do v.iter().any |e| { e.is_negative() } => { } _ => { fail!("wrong answer."); @@ -58,7 +58,7 @@ pub fn main() { // In the tail of a block let w = - if true { do abs_v.iter().any_ |e| { e.is_positive() } } + if true { do abs_v.iter().any |e| { e.is_positive() } } else { false }; assert!(w); } diff --git a/src/test/run-pass/test-ignore-cfg.rs b/src/test/run-pass/test-ignore-cfg.rs index e7a23244c06b..068f18ac0f83 100644 --- a/src/test/run-pass/test-ignore-cfg.rs +++ b/src/test/run-pass/test-ignore-cfg.rs @@ -29,8 +29,8 @@ fn checktests() { let tests = __test::tests; assert!( - tests.iter().any_(|t| t.desc.name.to_str() == ~"shouldignore" && t.desc.ignore)); + tests.iter().any(|t| t.desc.name.to_str() == ~"shouldignore" && t.desc.ignore)); assert!( - tests.iter().any_(|t| t.desc.name.to_str() == ~"shouldnotignore" && !t.desc.ignore)); + tests.iter().any(|t| t.desc.name.to_str() == ~"shouldnotignore" && !t.desc.ignore)); } From a02e37c397211c09467f374a60597efa1a57ea07 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 4 Jul 2013 14:58:02 -0700 Subject: [PATCH 86/93] Fix a warning when generating tests --- src/librustc/front/test.rs | 4 ++-- src/test/run-pass/test-ignore-cfg.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs index f2670a663ea0..f4d89f559f23 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -309,7 +309,7 @@ fn mk_test_module(cx: &TestCtxt) -> @ast::item { let mainfn = (quote_item!( pub fn main() { #[main]; - extra::test::test_main_static(::std::os::args(), tests); + extra::test::test_main_static(::std::os::args(), TESTS); } )).get(); @@ -366,7 +366,7 @@ fn mk_tests(cx: &TestCtxt) -> @ast::item { let test_descs = mk_test_descs(cx); (quote_item!( - pub static tests : &'static [self::extra::test::TestDescAndFn] = + pub static TESTS : &'static [self::extra::test::TestDescAndFn] = $test_descs ; )).get() diff --git a/src/test/run-pass/test-ignore-cfg.rs b/src/test/run-pass/test-ignore-cfg.rs index e7a23244c06b..e54bc7404b44 100644 --- a/src/test/run-pass/test-ignore-cfg.rs +++ b/src/test/run-pass/test-ignore-cfg.rs @@ -26,7 +26,7 @@ fn shouldnotignore() { #[test] fn checktests() { // Pull the tests out of the secreturn test module - let tests = __test::tests; + let tests = __test::TESTS; assert!( tests.iter().any_(|t| t.desc.name.to_str() == ~"shouldignore" && t.desc.ignore)); From d49acef07be04a2d32021dd1edadcf76582eda2c Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 3 Jul 2013 09:11:48 -0700 Subject: [PATCH 87/93] Add rusti/rustpkg to check-lite Ironically also disable rusti tests for now, but mainly because they're awaiting LLVM upgrades before proceeding --- mk/tests.mk | 3 ++- src/librusti/rusti.rs | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/mk/tests.mk b/mk/tests.mk index 9a991c151978..6b6f515ce2b5 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -15,7 +15,7 @@ # The names of crates that must be tested TEST_TARGET_CRATES = std extra -TEST_HOST_CRATES = syntax rustc rustdoc rust rustpkg +TEST_HOST_CRATES = syntax rustc rustdoc rust rustpkg rusti TEST_CRATES = $(TEST_TARGET_CRATES) $(TEST_HOST_CRATES) # Markdown files under doc/ that should have their code extracted and run @@ -157,6 +157,7 @@ check-test: cleantestlibs cleantmptestlogs all check-stage2-rfail check-lite: cleantestlibs cleantmptestlogs \ check-stage2-std check-stage2-extra check-stage2-rpass \ + check-stage2-rustpkg check-stage2-rusti \ check-stage2-rfail check-stage2-cfail $(Q)$(CFG_PYTHON) $(S)src/etc/check-summary.py tmp/*.log diff --git a/src/librusti/rusti.rs b/src/librusti/rusti.rs index d9cd52201c0c..5399ff6272d4 100644 --- a/src/librusti/rusti.rs +++ b/src/librusti/rusti.rs @@ -530,7 +530,8 @@ mod tests { // FIXME: #7220 rusti on 32bit mac doesn't work. // FIXME: #7641 rusti on 32bit linux cross compile doesn't work - #[cfg(not(target_word_size="32"))] + // FIXME: #7115 re-enable once LLVM has been upgraded + #[cfg(thiswillneverbeacfgflag)] fn run_program(prog: &str) { let mut r = repl(); for prog.split_iter('\n').advance |cmd| { @@ -539,7 +540,6 @@ mod tests { r = result.expect(fmt!("the command '%s' failed", cmd)); } } - #[cfg(target_word_size="32")] fn run_program(_: &str) {} #[test] From 7bf34c34377986d73376967c7ca967f3bc484c1f Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Mon, 1 Jul 2013 20:59:54 -0400 Subject: [PATCH 88/93] vec: make vec_reserve_shared_actual private --- src/libstd/vec.rs | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index effbc008b6ac..8c8874e2a751 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -33,28 +33,15 @@ use sys::size_of; use uint; use unstable::intrinsics; #[cfg(stage0)] -use intrinsic::{get_tydesc}; +use intrinsic::{get_tydesc, TyDesc}; #[cfg(not(stage0))] -use unstable::intrinsics::{get_tydesc, contains_managed}; +use unstable::intrinsics::{get_tydesc, contains_managed, TyDesc}; use vec; use util; -#[doc(hidden)] -pub mod rustrt { - use libc; - use vec::raw; - #[cfg(stage0)] - use intrinsic::{TyDesc}; - #[cfg(not(stage0))] - use unstable::intrinsics::{TyDesc}; - - #[abi = "cdecl"] - pub extern { - #[fast_ffi] - unsafe fn vec_reserve_shared_actual(t: *TyDesc, - v: **raw::VecRepr, - n: libc::size_t); - } +extern { + #[fast_ffi] + unsafe fn vec_reserve_shared_actual(t: *TyDesc, v: **raw::VecRepr, n: libc::size_t); } /// Returns true if two vectors have the same length @@ -1152,7 +1139,7 @@ impl OwnedVector for ~[T] { let td = get_tydesc::(); if ((**ptr).box_header.ref_count == managed::raw::RC_MANAGED_UNIQUE) { - rustrt::vec_reserve_shared_actual(td, ptr as **raw::VecRepr, n as libc::size_t); + vec_reserve_shared_actual(td, ptr as **raw::VecRepr, n as libc::size_t); } else { let alloc = n * sys::nonzero_size_of::(); *ptr = realloc_raw(*ptr as *mut c_void, alloc + size_of::()) @@ -1182,7 +1169,7 @@ impl OwnedVector for ~[T] { let ptr: *mut *mut raw::VecRepr = cast::transmute(self); let td = get_tydesc::(); if contains_managed::() { - rustrt::vec_reserve_shared_actual(td, ptr as **raw::VecRepr, n as libc::size_t); + vec_reserve_shared_actual(td, ptr as **raw::VecRepr, n as libc::size_t); } else { let alloc = n * sys::nonzero_size_of::(); *ptr = realloc_raw(*ptr as *mut c_void, alloc + size_of::()) From 0aedecf96b08c41ea481eaaebd4e5d2e2325d9c9 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Tue, 2 Jul 2013 19:24:58 -0400 Subject: [PATCH 89/93] add a temporary vector_exchange_malloc lang item --- src/librustc/middle/lang_items.rs | 70 ++++++++++++++++------------- src/librustc/middle/trans/base.rs | 5 ++- src/librustc/middle/trans/common.rs | 3 +- src/librustc/middle/trans/expr.rs | 2 +- src/librustc/middle/trans/tvec.rs | 14 ++++-- src/libstd/rt/global_heap.rs | 8 ++++ 6 files changed, 64 insertions(+), 38 deletions(-) diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 0e9361193b0a..d4d1997a56f2 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -63,33 +63,34 @@ pub enum LangItem { FailFnLangItem, // 24 FailBoundsCheckFnLangItem, // 25 ExchangeMallocFnLangItem, // 26 - ClosureExchangeMallocFnLangItem, // 27 - ExchangeFreeFnLangItem, // 28 - MallocFnLangItem, // 29 - FreeFnLangItem, // 30 - BorrowAsImmFnLangItem, // 31 - BorrowAsMutFnLangItem, // 32 - ReturnToMutFnLangItem, // 33 - CheckNotBorrowedFnLangItem, // 34 - StrDupUniqFnLangItem, // 35 - RecordBorrowFnLangItem, // 36 - UnrecordBorrowFnLangItem, // 37 + VectorExchangeMallocFnLangItem, // 27 + ClosureExchangeMallocFnLangItem, // 28 + ExchangeFreeFnLangItem, // 29 + MallocFnLangItem, // 30 + FreeFnLangItem, // 31 + BorrowAsImmFnLangItem, // 32 + BorrowAsMutFnLangItem, // 33 + ReturnToMutFnLangItem, // 34 + CheckNotBorrowedFnLangItem, // 35 + StrDupUniqFnLangItem, // 36 + RecordBorrowFnLangItem, // 37 + UnrecordBorrowFnLangItem, // 38 - StartFnLangItem, // 38 + StartFnLangItem, // 39 - TyDescStructLangItem, // 39 - TyVisitorTraitLangItem, // 40 - OpaqueStructLangItem, // 41 + TyDescStructLangItem, // 40 + TyVisitorTraitLangItem, // 41 + OpaqueStructLangItem, // 42 } pub struct LanguageItems { - items: [Option, ..42] + items: [Option, ..43] } impl LanguageItems { pub fn new() -> LanguageItems { LanguageItems { - items: [ None, ..42 ] + items: [ None, ..43 ] } } @@ -129,23 +130,24 @@ impl LanguageItems { 24 => "fail_", 25 => "fail_bounds_check", 26 => "exchange_malloc", - 27 => "closure_exchange_malloc", - 28 => "exchange_free", - 29 => "malloc", - 30 => "free", - 31 => "borrow_as_imm", - 32 => "borrow_as_mut", - 33 => "return_to_mut", - 34 => "check_not_borrowed", - 35 => "strdup_uniq", - 36 => "record_borrow", - 37 => "unrecord_borrow", + 27 => "vector_exchange_malloc", + 28 => "closure_exchange_malloc", + 29 => "exchange_free", + 30 => "malloc", + 31 => "free", + 32 => "borrow_as_imm", + 33 => "borrow_as_mut", + 34 => "return_to_mut", + 35 => "check_not_borrowed", + 36 => "strdup_uniq", + 37 => "record_borrow", + 38 => "unrecord_borrow", - 38 => "start", + 39 => "start", - 39 => "ty_desc", - 40 => "ty_visitor", - 41 => "opaque", + 40 => "ty_desc", + 41 => "ty_visitor", + 42 => "opaque", _ => "???" } @@ -238,6 +240,9 @@ impl LanguageItems { pub fn exchange_malloc_fn(&self) -> def_id { self.items[ExchangeMallocFnLangItem as uint].get() } + pub fn vector_exchange_malloc_fn(&self) -> def_id { + self.items[VectorExchangeMallocFnLangItem as uint].get() + } pub fn closure_exchange_malloc_fn(&self) -> def_id { self.items[ClosureExchangeMallocFnLangItem as uint].get() } @@ -331,6 +336,7 @@ impl<'self> LanguageItemCollector<'self> { item_refs.insert(@"fail_bounds_check", FailBoundsCheckFnLangItem as uint); item_refs.insert(@"exchange_malloc", ExchangeMallocFnLangItem as uint); + item_refs.insert(@"vector_exchange_malloc", VectorExchangeMallocFnLangItem as uint); item_refs.insert(@"closure_exchange_malloc", ClosureExchangeMallocFnLangItem as uint); item_refs.insert(@"exchange_free", ExchangeFreeFnLangItem as uint); item_refs.insert(@"malloc", MallocFnLangItem as uint); diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 09415742b7be..f22bc2084ce1 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -296,12 +296,15 @@ pub fn malloc_raw_dyn(bcx: block, heap_exchange => { (ty::mk_imm_uniq, bcx.tcx().lang_items.exchange_malloc_fn()) } + heap_exchange_vector => { + (ty::mk_imm_uniq, bcx.tcx().lang_items.vector_exchange_malloc_fn()) + } heap_exchange_closure => { (ty::mk_imm_uniq, bcx.tcx().lang_items.closure_exchange_malloc_fn()) } }; - if heap == heap_exchange { + if heap == heap_exchange || heap == heap_exchange_vector { // Grab the TypeRef type of box_ptr_ty. let box_ptr_ty = mk_fn(bcx.tcx(), t); let llty = type_of(ccx, box_ptr_ty); diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 19c94d95c4f9..fb8fa4d6bacc 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -274,6 +274,7 @@ pub enum heap { heap_managed, heap_managed_unique, heap_exchange, + heap_exchange_vector, heap_exchange_closure } @@ -395,7 +396,7 @@ pub fn add_clean_free(cx: block, ptr: ValueRef, heap: heap) { let f: @fn(block) -> block = |a| glue::trans_free(a, ptr); f } - heap_exchange | heap_exchange_closure => { + heap_exchange | heap_exchange_vector | heap_exchange_closure => { let f: @fn(block) -> block = |a| glue::trans_exchange_free(a, ptr); f } diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 9c831db514a5..a0d29d56effb 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -464,7 +464,7 @@ fn trans_rvalue_datum_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { expr, contents); } ast::expr_vstore(contents, ast::expr_vstore_uniq) => { - let heap = heap_for_unique(bcx, expr_ty(bcx, contents)); + let heap = tvec::heap_for_unique_vector(bcx, expr_ty(bcx, contents)); return tvec::trans_uniq_or_managed_vstore(bcx, heap, expr, contents); } diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index 233508c5f668..8ff462fbdeec 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -95,9 +95,17 @@ pub fn alloc_raw(bcx: block, unit_ty: ty::t, return rslt(bcx, bx); } +pub fn heap_for_unique_vector(bcx: block, t: ty::t) -> heap { + if ty::type_contents(bcx.tcx(), t).contains_managed() { + heap_managed_unique + } else { + heap_exchange_vector + } +} + pub fn alloc_uniq_raw(bcx: block, unit_ty: ty::t, fill: ValueRef, alloc: ValueRef) -> Result { - alloc_raw(bcx, unit_ty, fill, alloc, base::heap_for_unique(bcx, unit_ty)) + alloc_raw(bcx, unit_ty, fill, alloc, heap_for_unique_vector(bcx, unit_ty)) } pub fn alloc_vec(bcx: block, @@ -298,7 +306,7 @@ pub fn trans_uniq_or_managed_vstore(bcx: block, heap: heap, vstore_expr: @ast::e // Handle ~"". match heap { - heap_exchange => { + heap_exchange_vector => { match content_expr.node { ast::expr_lit(@codemap::spanned { node: ast::lit_str(s), _ @@ -321,7 +329,7 @@ pub fn trans_uniq_or_managed_vstore(bcx: block, heap: heap, vstore_expr: @ast::e _ => {} } } - heap_exchange_closure => fail!("vectors are not allocated with closure_exchange_alloc"), + heap_exchange | heap_exchange_closure => fail!("vectors use vector_exchange_alloc"), heap_managed | heap_managed_unique => {} } diff --git a/src/libstd/rt/global_heap.rs b/src/libstd/rt/global_heap.rs index 1020580d52c0..0e5b64273572 100644 --- a/src/libstd/rt/global_heap.rs +++ b/src/libstd/rt/global_heap.rs @@ -85,6 +85,14 @@ pub unsafe fn exchange_malloc(align: u32, size: uintptr_t) -> *c_char { malloc_raw(total_size as uint) as *c_char } +#[cfg(not(test))] +#[lang="vector_exchange_malloc"] +#[inline] +pub unsafe fn vector_exchange_malloc(align: u32, size: uintptr_t) -> *c_char { + let total_size = get_box_size(size as uint, align as uint); + malloc_raw(total_size as uint) as *c_char +} + // FIXME: #7496 #[cfg(not(test))] #[lang="closure_exchange_malloc"] From 90f1db10fa29eb6b91e22037f13130f854da1401 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Tue, 2 Jul 2013 19:51:39 -0400 Subject: [PATCH 90/93] remove headers from exchange allocations --- src/librustc/middle/trans/_match.rs | 12 ++++- src/librustc/middle/trans/base.rs | 59 ++++++++++++++----------- src/librustc/middle/trans/datum.rs | 24 +++++++--- src/librustc/middle/trans/expr.rs | 24 +++++++--- src/librustc/middle/trans/glue.rs | 4 +- src/librustc/middle/trans/meth.rs | 5 +++ src/librustc/middle/trans/reflect.rs | 6 ++- src/librustc/middle/trans/tvec.rs | 19 +++++++- src/librustc/middle/trans/type_of.rs | 29 +++--------- src/librustc/middle/trans/uniq.rs | 26 ++++++++--- src/libstd/reflect.rs | 8 ++++ src/libstd/repr.rs | 9 ++++ src/libstd/rt/global_heap.rs | 5 +-- src/libstd/unstable/intrinsics.rs | 1 + src/test/run-pass/reflect-visit-data.rs | 8 ++++ src/test/run-pass/reflect-visit-type.rs | 1 + 16 files changed, 165 insertions(+), 75 deletions(-) diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 3e828a891d49..241b97e0e2ab 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -1395,8 +1395,12 @@ pub fn compile_submatch(bcx: block, } if any_uniq_pat(m, col) { + let pat_ty = node_id_type(bcx, pat_id); let llbox = Load(bcx, val); - let unboxed = GEPi(bcx, llbox, [0u, abi::box_field_body]); + let unboxed = match ty::get(pat_ty).sty { + ty::ty_uniq(*) if !ty::type_contents(bcx.tcx(), pat_ty).contains_managed() => llbox, + _ => GEPi(bcx, llbox, [0u, abi::box_field_body]) + }; compile_submatch(bcx, enter_uniq(bcx, dm, m, col, val), vec::append(~[unboxed], vals_left), chk); return; @@ -1868,8 +1872,12 @@ pub fn bind_irrefutable_pat(bcx: block, } } ast::pat_box(inner) | ast::pat_uniq(inner) => { + let pat_ty = node_id_type(bcx, pat.id); let llbox = Load(bcx, val); - let unboxed = GEPi(bcx, llbox, [0u, abi::box_field_body]); + let unboxed = match ty::get(pat_ty).sty { + ty::ty_uniq(*) if !ty::type_contents(bcx.tcx(), pat_ty).contains_managed() => llbox, + _ => GEPi(bcx, llbox, [0u, abi::box_field_body]) + }; bcx = bind_irrefutable_pat(bcx, inner, unboxed, diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index f22bc2084ce1..e2795f77d7d8 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -289,24 +289,25 @@ pub fn malloc_raw_dyn(bcx: block, let _icx = push_ctxt("malloc_raw"); let ccx = bcx.ccx(); - let (mk_fn, langcall) = match heap { - heap_managed | heap_managed_unique => { - (ty::mk_imm_box, bcx.tcx().lang_items.malloc_fn()) - } - heap_exchange => { - (ty::mk_imm_uniq, bcx.tcx().lang_items.exchange_malloc_fn()) - } - heap_exchange_vector => { - (ty::mk_imm_uniq, bcx.tcx().lang_items.vector_exchange_malloc_fn()) - } - heap_exchange_closure => { - (ty::mk_imm_uniq, bcx.tcx().lang_items.closure_exchange_malloc_fn()) - } - }; + if heap == heap_exchange { + let llty_value = type_of::type_of(ccx, t); + let llalign = llalign_of_min(ccx, llty_value); - if heap == heap_exchange || heap == heap_exchange_vector { + // Allocate space: + let rval = alloca(bcx, Type::i8p()); + let bcx = callee::trans_lang_call( + bcx, + bcx.tcx().lang_items.exchange_malloc_fn(), + [C_i32(llalign as i32), size], + expr::SaveIn(rval)); + rslt(bcx, PointerCast(bcx, Load(bcx, rval), llty_value.ptr_to())) + } else if heap == heap_exchange_vector { // Grab the TypeRef type of box_ptr_ty. - let box_ptr_ty = mk_fn(bcx.tcx(), t); + let element_type = match ty::get(t).sty { + ty::ty_unboxed_vec(e) => e, + _ => fail!("not a vector body") + }; + let box_ptr_ty = ty::mk_evec(bcx.tcx(), element_type, ty::vstore_uniq); let llty = type_of(ccx, box_ptr_ty); let llty_value = type_of::type_of(ccx, t); @@ -316,11 +317,22 @@ pub fn malloc_raw_dyn(bcx: block, let rval = alloca(bcx, Type::i8p()); let bcx = callee::trans_lang_call( bcx, - langcall, + bcx.tcx().lang_items.vector_exchange_malloc_fn(), [C_i32(llalign as i32), size], expr::SaveIn(rval)); rslt(bcx, PointerCast(bcx, Load(bcx, rval), llty)) } else { + // we treat ~fn, @fn and @[] as @ here, which isn't ideal + let (mk_fn, langcall) = match heap { + heap_managed | heap_managed_unique => { + (ty::mk_imm_box, bcx.tcx().lang_items.malloc_fn()) + } + heap_exchange_closure => { + (ty::mk_imm_box, bcx.tcx().lang_items.closure_exchange_malloc_fn()) + } + _ => fail!("heap_exchange/heap_exchange_vector already handled") + }; + // Grab the TypeRef type of box_ptr_ty. let box_ptr_ty = mk_fn(bcx.tcx(), t); let llty = type_of(ccx, box_ptr_ty); @@ -362,6 +374,7 @@ pub struct MallocResult { // and pulls out the body pub fn malloc_general_dyn(bcx: block, t: ty::t, heap: heap, size: ValueRef) -> MallocResult { + assert!(heap != heap_exchange); let _icx = push_ctxt("malloc_general"); let Result {bcx: bcx, val: llbox} = malloc_raw_dyn(bcx, t, heap, size); let body = GEPi(bcx, llbox, [0u, abi::box_field_body]); @@ -369,9 +382,9 @@ pub fn malloc_general_dyn(bcx: block, t: ty::t, heap: heap, size: ValueRef) MallocResult { bcx: bcx, box: llbox, body: body } } -pub fn malloc_general(bcx: block, t: ty::t, heap: heap) - -> MallocResult { - let ty = type_of(bcx.ccx(), t); +pub fn malloc_general(bcx: block, t: ty::t, heap: heap) -> MallocResult { + let ty = type_of(bcx.ccx(), t); + assert!(heap != heap_exchange); malloc_general_dyn(bcx, t, heap, llsize_of(bcx.ccx(), ty)) } pub fn malloc_boxed(bcx: block, t: ty::t) @@ -388,6 +401,7 @@ pub fn heap_for_unique(bcx: block, t: ty::t) -> heap { } pub fn maybe_set_managed_unique_rc(bcx: block, bx: ValueRef, heap: heap) { + assert!(heap != heap_exchange); if heap == heap_managed_unique { // In cases where we are looking at a unique-typed allocation in the // managed heap (thus have refcount 1 from the managed allocator), @@ -399,11 +413,6 @@ pub fn maybe_set_managed_unique_rc(bcx: block, bx: ValueRef, heap: heap) { } } -pub fn malloc_unique(bcx: block, t: ty::t) - -> MallocResult { - malloc_general(bcx, t, heap_for_unique(bcx, t)) -} - // Type descriptor and type glue stuff pub fn get_tydesc_simple(ccx: &mut CrateContext, t: ty::t) -> ValueRef { diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs index 8ee4b6644cbe..e86709d72b32 100644 --- a/src/librustc/middle/trans/datum.rs +++ b/src/librustc/middle/trans/datum.rs @@ -100,6 +100,7 @@ use middle::trans::glue; use middle::trans::tvec; use middle::trans::type_of; use middle::trans::write_guard; +use middle::trans::type_::Type; use middle::ty; use util::common::indenter; use util::ppaux::ty_to_str; @@ -567,8 +568,14 @@ impl Datum { * This datum must represent an @T or ~T box. Returns a new * by-ref datum of type T, pointing at the contents. */ - let content_ty = match ty::get(self.ty).sty { - ty::ty_box(mt) | ty::ty_uniq(mt) => mt.ty, + let (content_ty, header) = match ty::get(self.ty).sty { + ty::ty_box(mt) => (mt.ty, true), + ty::ty_uniq(mt) => (mt.ty, false), + ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) => { + let unit_ty = ty::sequence_element_type(bcx.tcx(), self.ty); + let unboxed_vec_ty = ty::mk_mut_unboxed_vec(bcx.tcx(), unit_ty); + (unboxed_vec_ty, true) + } _ => { bcx.tcx().sess.bug(fmt!( "box_body() invoked on non-box type %s", @@ -576,9 +583,16 @@ impl Datum { } }; - let ptr = self.to_value_llval(bcx); - let body = opaque_box_body(bcx, content_ty, ptr); - Datum {val: body, ty: content_ty, mode: ByRef(ZeroMem)} + if !header && !ty::type_contents(bcx.tcx(), content_ty).contains_managed() { + let ptr = self.to_value_llval(bcx); + let ty = type_of(bcx.ccx(), content_ty); + let body = PointerCast(bcx, ptr, ty.ptr_to()); + Datum {val: body, ty: content_ty, mode: ByRef(ZeroMem)} + } else { // has a header + let ptr = self.to_value_llval(bcx); + let body = opaque_box_body(bcx, content_ty, ptr); + Datum {val: body, ty: content_ty, mode: ByRef(ZeroMem)} + } } pub fn to_rptr(&self, bcx: block) -> Datum { diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index a0d29d56effb..d2a83814f312 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -150,6 +150,7 @@ use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowVecRef, AutoBorrowFn, use middle::ty; use util::common::indenter; use util::ppaux::Repr; +use middle::trans::machine::llsize_of; use middle::trans::type_::Type; @@ -1329,12 +1330,23 @@ fn trans_unary_datum(bcx: block, contents_ty: ty::t, heap: heap) -> DatumBlock { let _icx = push_ctxt("trans_boxed_expr"); - let base::MallocResult { bcx, box: bx, body } = - base::malloc_general(bcx, contents_ty, heap); - add_clean_free(bcx, bx, heap); - let bcx = trans_into(bcx, contents, SaveIn(body)); - revoke_clean(bcx, bx); - return immediate_rvalue_bcx(bcx, bx, box_ty); + if heap == heap_exchange { + let llty = type_of(bcx.ccx(), contents_ty); + let size = llsize_of(bcx.ccx(), llty); + let Result { bcx: bcx, val: val } = malloc_raw_dyn(bcx, contents_ty, + heap_exchange, size); + add_clean_free(bcx, val, heap_exchange); + let bcx = trans_into(bcx, contents, SaveIn(val)); + revoke_clean(bcx, val); + return immediate_rvalue_bcx(bcx, val, box_ty); + } else { + let base::MallocResult { bcx, box: bx, body } = + base::malloc_general(bcx, contents_ty, heap); + add_clean_free(bcx, bx, heap); + let bcx = trans_into(bcx, contents, SaveIn(body)); + revoke_clean(bcx, bx); + return immediate_rvalue_bcx(bcx, bx, box_ty); + } } } diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 84a91cf16150..682a4f133c08 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -386,7 +386,9 @@ pub fn make_free_glue(bcx: block, v: ValueRef, t: ty::t) { ty::ty_uniq(*) => { uniq::make_free_glue(bcx, v, t) } - ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) | + ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) => { + tvec::make_uniq_free_glue(bcx, v, t) + } ty::ty_evec(_, ty::vstore_box) | ty::ty_estr(ty::vstore_box) => { make_free_glue(bcx, v, tvec::expand_boxed_vec_ty(bcx.tcx(), t)); diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index ca469a42103a..14cc822b5a57 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -548,6 +548,7 @@ pub fn trans_trait_callee_from_llval(bcx: block, let _icx = push_ctxt("impl::trans_trait_callee"); let ccx = bcx.ccx(); + let mut bcx = bcx; // Load the vtable from the @Trait pair debug!("(translating trait callee) loading vtable from pair %s", @@ -576,6 +577,10 @@ pub fn trans_trait_callee_from_llval(bcx: block, } ast::sty_region(*) => { match store { + ty::UniqTraitStore + if !ty::type_contents(bcx.tcx(), callee_ty).contains_managed() => { + llself = llbox; + } ty::BoxTraitStore | ty::UniqTraitStore => { llself = GEPi(bcx, llbox, [0u, abi::box_field_body]); diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index 04133bfe79ac..de91993f345a 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -194,7 +194,11 @@ impl Reflector { } ty::ty_uniq(ref mt) => { let extra = self.c_mt(mt); - self.visit("uniq", extra) + if ty::type_contents(bcx.tcx(), t).contains_managed() { + self.visit("uniq_managed", extra) + } else { + self.visit("uniq", extra) + } } ty::ty_ptr(ref mt) => { let extra = self.c_mt(mt); diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index 8ff462fbdeec..809838ded0ab 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -33,6 +33,23 @@ use std::option::None; use syntax::ast; use syntax::codemap; +pub fn make_uniq_free_glue(bcx: block, vptrptr: ValueRef, box_ty: ty::t) + -> block { + let box_datum = immediate_rvalue(Load(bcx, vptrptr), box_ty); + + let not_null = IsNotNull(bcx, box_datum.val); + do with_cond(bcx, not_null) |bcx| { + let body_datum = box_datum.box_body(bcx); + let bcx = glue::drop_ty(bcx, body_datum.to_ref_llval(bcx), + body_datum.ty); + if ty::type_contents(bcx.tcx(), box_ty).contains_managed() { + glue::trans_free(bcx, box_datum.val) + } else { + glue::trans_exchange_free(bcx, box_datum.val) + } + } +} + // Boxed vector types are in some sense currently a "shorthand" for a box // containing an unboxed vector. This expands a boxed vector type into such an // expanded type. It doesn't respect mutability, but that doesn't matter at @@ -42,7 +59,7 @@ pub fn expand_boxed_vec_ty(tcx: ty::ctxt, t: ty::t) -> ty::t { let unboxed_vec_ty = ty::mk_mut_unboxed_vec(tcx, unit_ty); match ty::get(t).sty { ty::ty_estr(ty::vstore_uniq) | ty::ty_evec(_, ty::vstore_uniq) => { - ty::mk_imm_uniq(tcx, unboxed_vec_ty) + fail!("cannot treat vectors/strings as exchange allocations yet"); } ty::ty_estr(ty::vstore_box) | ty::ty_evec(_, ty::vstore_box) => { ty::mk_imm_box(tcx, unboxed_vec_ty) diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index e6d0d87ba73c..1d2048161757 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -72,29 +72,6 @@ pub fn type_of_fn_from_ty(cx: &mut CrateContext, fty: ty::t) -> Type { } } -pub fn type_of_non_gc_box(cx: &mut CrateContext, t: ty::t) -> Type { - assert!(!ty::type_needs_infer(t)); - - let t_norm = ty::normalize_ty(cx.tcx, t); - if t != t_norm { - type_of_non_gc_box(cx, t_norm) - } else { - match ty::get(t).sty { - ty::ty_box(mt) => { - let ty = type_of(cx, mt.ty); - Type::box(cx, &ty).ptr_to() - } - ty::ty_uniq(mt) => { - let ty = type_of(cx, mt.ty); - Type::unique(cx, &ty).ptr_to() - } - _ => { - cx.sess.bug("non-box in type_of_non_gc_box"); - } - } - } -} - // A "sizing type" is an LLVM type, the size and alignment of which are // guaranteed to be equivalent to what you would get out of `type_of()`. It's // useful because: @@ -231,7 +208,11 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type { ty::ty_opaque_box => Type::opaque_box(cx).ptr_to(), ty::ty_uniq(ref mt) => { let ty = type_of(cx, mt.ty); - Type::unique(cx, &ty).ptr_to() + if ty::type_contents(cx.tcx, mt.ty).contains_managed() { + Type::unique(cx, &ty).ptr_to() + } else { + ty.ptr_to() + } } ty::ty_evec(ref mt, ty::vstore_uniq) => { let ty = type_of(cx, mt.ty); diff --git a/src/librustc/middle/trans/uniq.rs b/src/librustc/middle/trans/uniq.rs index adecd61bc4f4..df9e29cad7f7 100644 --- a/src/librustc/middle/trans/uniq.rs +++ b/src/librustc/middle/trans/uniq.rs @@ -17,6 +17,9 @@ use middle::trans::datum::immediate_rvalue; use middle::trans::datum; use middle::trans::glue; use middle::ty; +use middle::trans::machine::llsize_of; +use middle::trans::type_of; +use middle::trans::type_of::*; pub fn make_free_glue(bcx: block, vptrptr: ValueRef, box_ty: ty::t) -> block { @@ -44,12 +47,21 @@ pub fn duplicate(bcx: block, src_box: ValueRef, src_ty: ty::t) -> Result { let body_datum = src_datum.box_body(bcx); // Malloc space in exchange heap and copy src into it - let MallocResult { - bcx: bcx, - box: dst_box, - body: dst_body - } = malloc_unique(bcx, body_datum.ty); - body_datum.copy_to(bcx, datum::INIT, dst_body); + if ty::type_contents(bcx.tcx(), src_ty).contains_managed() { + let MallocResult { + bcx: bcx, + box: dst_box, + body: dst_body + } = malloc_general(bcx, body_datum.ty, heap_managed_unique); + body_datum.copy_to(bcx, datum::INIT, dst_body); - rslt(bcx, dst_box) + rslt(bcx, dst_box) + } else { + let body_datum = body_datum.to_value_datum(bcx); + let llty = type_of(bcx.ccx(), body_datum.ty); + let size = llsize_of(bcx.ccx(), llty); + let Result { bcx: bcx, val: val } = malloc_raw_dyn(bcx, body_datum.ty, heap_exchange, size); + body_datum.copy_to(bcx, datum::INIT, val); + Result { bcx: bcx, val: val } + } } diff --git a/src/libstd/reflect.rs b/src/libstd/reflect.rs index 16ab4771d0de..9075133b0861 100644 --- a/src/libstd/reflect.rs +++ b/src/libstd/reflect.rs @@ -248,6 +248,14 @@ impl TyVisitor for MovePtrAdaptor { true } + #[cfg(not(stage0))] + fn visit_uniq_managed(&self, mtbl: uint, inner: *TyDesc) -> bool { + self.align_to::<~u8>(); + if ! self.inner.visit_uniq_managed(mtbl, inner) { return false; } + self.bump_past::<~u8>(); + true + } + fn visit_ptr(&self, mtbl: uint, inner: *TyDesc) -> bool { self.align_to::<*u8>(); if ! self.inner.visit_ptr(mtbl, inner) { return false; } diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs index fdda65d3e95b..dd5075f8e668 100644 --- a/src/libstd/repr.rs +++ b/src/libstd/repr.rs @@ -300,6 +300,15 @@ impl TyVisitor for ReprVisitor { } fn visit_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool { + self.writer.write_char('~'); + self.write_mut_qualifier(mtbl); + do self.get::<*c_void> |b| { + self.visit_ptr_inner(*b, inner); + } + } + + #[cfg(not(stage0))] + fn visit_uniq_managed(&self, mtbl: uint, inner: *TyDesc) -> bool { self.writer.write_char('~'); self.write_mut_qualifier(mtbl); do self.get::<&managed::raw::BoxRepr> |b| { diff --git a/src/libstd/rt/global_heap.rs b/src/libstd/rt/global_heap.rs index 0e5b64273572..54deb8924f5c 100644 --- a/src/libstd/rt/global_heap.rs +++ b/src/libstd/rt/global_heap.rs @@ -80,9 +80,8 @@ pub unsafe fn exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char { #[cfg(not(stage0), not(test))] #[lang="exchange_malloc"] #[inline] -pub unsafe fn exchange_malloc(align: u32, size: uintptr_t) -> *c_char { - let total_size = get_box_size(size as uint, align as uint); - malloc_raw(total_size as uint) as *c_char +pub unsafe fn exchange_malloc(_align: u32, size: uintptr_t) -> *c_char { + malloc_raw(size as uint) as *c_char } #[cfg(not(test))] diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index 97e3cba92db2..ce5ccf2401db 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -91,6 +91,7 @@ pub trait TyVisitor { fn visit_box(&self, mtbl: uint, inner: *TyDesc) -> bool; fn visit_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool; + fn visit_uniq_managed(&self, mtbl: uint, inner: *TyDesc) -> bool; fn visit_ptr(&self, mtbl: uint, inner: *TyDesc) -> bool; fn visit_rptr(&self, mtbl: uint, inner: *TyDesc) -> bool; diff --git a/src/test/run-pass/reflect-visit-data.rs b/src/test/run-pass/reflect-visit-data.rs index 176e49e0ea19..53b39d5ed303 100644 --- a/src/test/run-pass/reflect-visit-data.rs +++ b/src/test/run-pass/reflect-visit-data.rs @@ -232,6 +232,13 @@ impl TyVisitor for ptr_visit_adaptor { true } + fn visit_uniq_managed(&self, mtbl: uint, inner: *TyDesc) -> bool { + self.align_to::<~u8>(); + if ! self.inner.visit_uniq_managed(mtbl, inner) { return false; } + self.bump_past::<~u8>(); + true + } + fn visit_ptr(&self, mtbl: uint, inner: *TyDesc) -> bool { self.align_to::<*u8>(); if ! self.inner.visit_ptr(mtbl, inner) { return false; } @@ -552,6 +559,7 @@ impl TyVisitor for my_visitor { fn visit_box(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } fn visit_uniq(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } + fn visit_uniq_managed(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } fn visit_ptr(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } fn visit_rptr(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } diff --git a/src/test/run-pass/reflect-visit-type.rs b/src/test/run-pass/reflect-visit-type.rs index bb1c92dfa8a7..4ce229526ffb 100644 --- a/src/test/run-pass/reflect-visit-type.rs +++ b/src/test/run-pass/reflect-visit-type.rs @@ -70,6 +70,7 @@ impl TyVisitor for MyVisitor { fn visit_box(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } fn visit_uniq(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } + fn visit_uniq_managed(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } fn visit_ptr(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } fn visit_rptr(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } From 4a485f8cec524c8f3f57e4fd3248d5093ed3dc5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Mon, 8 Jul 2013 07:42:56 +0200 Subject: [PATCH 91/93] Avoid unused allocas for immediate return values There's no need to allocate a return slot for anykind of immediate return value, not just not for nils. Also, when the return value is ignored, we only have to copy it to a temporary alloca if it's actually required to call drop_ty on it. --- src/librustc/middle/trans/callee.rs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 05fe0bed3b69..2a5e8f2ddc06 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -672,15 +672,8 @@ pub fn trans_call_inner(in_cx: block, expr::Ignore => { // drop the value if it is not being saved. unsafe { - if llvm::LLVMIsUndef(llretslot) != lib::llvm::True { - if ty::type_is_nil(ret_ty) { - // When implementing the for-loop sugar syntax, the - // type of the for-loop is nil, but the function - // it's invoking returns a bool. This is a special - // case to ignore instead of invoking the Store - // below into a scratch pointer of a mismatched - // type. - } else if ty::type_is_immediate(bcx.tcx(), ret_ty) { + if ty::type_needs_drop(bcx.tcx(), ret_ty) { + if ty::type_is_immediate(bcx.tcx(), ret_ty) { let llscratchptr = alloc_ty(bcx, ret_ty); Store(bcx, llresult, llscratchptr); bcx = glue::drop_ty(bcx, llscratchptr, ret_ty); @@ -734,7 +727,7 @@ pub fn trans_ret_slot(bcx: block, fn_ty: ty::t, dest: expr::Dest) match dest { expr::SaveIn(dst) => dst, expr::Ignore => { - if ty::type_is_nil(retty) { + if ty::type_is_immediate(bcx.tcx(), retty) { unsafe { llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref()) } From 00ba8b3ac0692293511858cae6fe1a3e1dcc316b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Mon, 8 Jul 2013 08:12:01 +0200 Subject: [PATCH 92/93] Improve handling of immediate return values We currently still handle immediate return values a lot like non-immediate ones. We provide a slot for them and store them into memory, often just to immediately load them again. To improve this situation, trans_call_inner has to return a Result which contains the immediate return value. Also, it also needs to accept "No destination" in addition to just SaveIn and Ignore. Since "No destination" isn't something that fits well into the Dest type, I've chosen to simply use Option instead, paired with an assertion that checks that "None" is only allowed for immediate return values. --- src/librustc/middle/trans/_match.rs | 10 ++----- src/librustc/middle/trans/base.rs | 21 +++++++-------- src/librustc/middle/trans/callee.rs | 33 ++++++++++++------------ src/librustc/middle/trans/closure.rs | 8 +++--- src/librustc/middle/trans/controlflow.rs | 4 +-- src/librustc/middle/trans/expr.rs | 4 +-- src/librustc/middle/trans/foreign.rs | 2 +- src/librustc/middle/trans/glue.rs | 4 +-- src/librustc/middle/trans/reflect.rs | 9 +++---- src/librustc/middle/trans/tvec.rs | 2 +- src/librustc/middle/trans/write_guard.rs | 16 ++++++------ 11 files changed, 51 insertions(+), 62 deletions(-) diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 80654342d0de..b7168cbfdec5 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -1095,26 +1095,20 @@ pub fn compare_values(cx: block, match ty::get(rhs_t).sty { ty::ty_estr(ty::vstore_uniq) => { - let scratch_result = scratch_datum(cx, ty::mk_bool(), false); let scratch_lhs = alloca(cx, val_ty(lhs)); Store(cx, lhs, scratch_lhs); let scratch_rhs = alloca(cx, val_ty(rhs)); Store(cx, rhs, scratch_rhs); let did = cx.tcx().lang_items.uniq_str_eq_fn(); - let bcx = callee::trans_lang_call(cx, did, [scratch_lhs, scratch_rhs], - expr::SaveIn(scratch_result.val)); - let result = scratch_result.to_result(bcx); + let result = callee::trans_lang_call(cx, did, [scratch_lhs, scratch_rhs], None); Result { bcx: result.bcx, val: bool_to_i1(result.bcx, result.val) } } ty::ty_estr(_) => { - let scratch_result = scratch_datum(cx, ty::mk_bool(), false); let did = cx.tcx().lang_items.str_eq_fn(); - let bcx = callee::trans_lang_call(cx, did, [lhs, rhs], - expr::SaveIn(scratch_result.val)); - let result = scratch_result.to_result(bcx); + let result = callee::trans_lang_call(cx, did, [lhs, rhs], None); Result { bcx: result.bcx, val: bool_to_i1(result.bcx, result.val) diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index e2795f77d7d8..577f1c689606 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -294,13 +294,12 @@ pub fn malloc_raw_dyn(bcx: block, let llalign = llalign_of_min(ccx, llty_value); // Allocate space: - let rval = alloca(bcx, Type::i8p()); - let bcx = callee::trans_lang_call( + let r = callee::trans_lang_call( bcx, bcx.tcx().lang_items.exchange_malloc_fn(), [C_i32(llalign as i32), size], - expr::SaveIn(rval)); - rslt(bcx, PointerCast(bcx, Load(bcx, rval), llty_value.ptr_to())) + None); + rslt(r.bcx, PointerCast(r.bcx, r.val, llty_value.ptr_to())) } else if heap == heap_exchange_vector { // Grab the TypeRef type of box_ptr_ty. let element_type = match ty::get(t).sty { @@ -314,13 +313,12 @@ pub fn malloc_raw_dyn(bcx: block, let llalign = llalign_of_min(ccx, llty_value); // Allocate space: - let rval = alloca(bcx, Type::i8p()); - let bcx = callee::trans_lang_call( + let r = callee::trans_lang_call( bcx, bcx.tcx().lang_items.vector_exchange_malloc_fn(), [C_i32(llalign as i32), size], - expr::SaveIn(rval)); - rslt(bcx, PointerCast(bcx, Load(bcx, rval), llty)) + None); + rslt(r.bcx, PointerCast(r.bcx, r.val, llty)) } else { // we treat ~fn, @fn and @[] as @ here, which isn't ideal let (mk_fn, langcall) = match heap { @@ -343,13 +341,12 @@ pub fn malloc_raw_dyn(bcx: block, // Allocate space: let tydesc = PointerCast(bcx, static_ti.tydesc, Type::i8p()); - let rval = alloca(bcx, Type::i8p()); - let bcx = callee::trans_lang_call( + let r = callee::trans_lang_call( bcx, langcall, [tydesc, size], - expr::SaveIn(rval)); - let r = rslt(bcx, PointerCast(bcx, Load(bcx, rval), llty)); + None); + let r = rslt(r.bcx, PointerCast(r.bcx, r.val, llty)); maybe_set_managed_unique_rc(r.bcx, r.val, heap); r } diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 2a5e8f2ddc06..473afda48e65 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -446,8 +446,8 @@ pub fn trans_call(in_cx: block, node_id_type(in_cx, id), |cx| trans(cx, f), args, - dest, - DontAutorefArg) + Some(dest), + DontAutorefArg).bcx } pub fn trans_method_call(in_cx: block, @@ -484,15 +484,15 @@ pub fn trans_method_call(in_cx: block, } }, args, - dest, - DontAutorefArg) + Some(dest), + DontAutorefArg).bcx } pub fn trans_lang_call(bcx: block, did: ast::def_id, args: &[ValueRef], - dest: expr::Dest) - -> block { + dest: Option) + -> Result { let fty = if did.crate == ast::local_crate { ty::node_id_to_type(bcx.ccx().tcx, did.node) } else { @@ -552,7 +552,7 @@ pub fn trans_lang_call_with_type_params(bcx: block, } Callee { bcx: callee.bcx, data: Fn(FnData { llfn: new_llval }) } }, - ArgVals(args), dest, DontAutorefArg); + ArgVals(args), Some(dest), DontAutorefArg).bcx; } pub fn body_contains_ret(body: &ast::blk) -> bool { @@ -579,10 +579,10 @@ pub fn trans_call_inner(in_cx: block, ret_ty: ty::t, get_callee: &fn(block) -> Callee, args: CallArgs, - dest: expr::Dest, + dest: Option, autoref_arg: AutorefArg) - -> block { - do base::with_scope(in_cx, call_info, "call") |cx| { + -> Result { + do base::with_scope_result(in_cx, call_info, "call") |cx| { let ret_in_loop = match args { ArgExprs(args) => { args.len() > 0u && match args.last().node { @@ -669,7 +669,8 @@ pub fn trans_call_inner(in_cx: block, bcx = new_bcx; match dest { - expr::Ignore => { + None => { assert!(ty::type_is_immediate(bcx.tcx(), ret_ty)) } + Some(expr::Ignore) => { // drop the value if it is not being saved. unsafe { if ty::type_needs_drop(bcx.tcx(), ret_ty) { @@ -683,7 +684,7 @@ pub fn trans_call_inner(in_cx: block, } } } - expr::SaveIn(lldest) => { + Some(expr::SaveIn(lldest)) => { // If this is an immediate, store into the result location. // (If this was not an immediate, the result will already be // directly written into the output slot.) @@ -710,7 +711,7 @@ pub fn trans_call_inner(in_cx: block, bcx } } - bcx + rslt(bcx, llresult) } } @@ -720,13 +721,13 @@ pub enum CallArgs<'self> { ArgVals(&'self [ValueRef]) } -pub fn trans_ret_slot(bcx: block, fn_ty: ty::t, dest: expr::Dest) +pub fn trans_ret_slot(bcx: block, fn_ty: ty::t, dest: Option) -> ValueRef { let retty = ty::ty_fn_ret(fn_ty); match dest { - expr::SaveIn(dst) => dst, - expr::Ignore => { + Some(expr::SaveIn(dst)) => dst, + _ => { if ty::type_is_immediate(bcx.tcx(), retty) { unsafe { llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref()) diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index 3478925753e2..4c63b8dc8445 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -531,13 +531,13 @@ pub fn make_opaque_cbox_take_glue( // Allocate memory, update original ptr, and copy existing data let opaque_tydesc = PointerCast(bcx, tydesc, Type::i8p()); - let rval = alloca(bcx, Type::i8p()); - let bcx = callee::trans_lang_call( + let mut bcx = bcx; + let llresult = unpack_result!(bcx, callee::trans_lang_call( bcx, bcx.tcx().lang_items.closure_exchange_malloc_fn(), [opaque_tydesc, sz], - expr::SaveIn(rval)); - let cbox_out = PointerCast(bcx, Load(bcx, rval), llopaquecboxty); + None)); + let cbox_out = PointerCast(bcx, llresult, llopaquecboxty); call_memcpy(bcx, cbox_out, cbox_in, sz, 1); Store(bcx, cbox_out, cboxptr); diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs index db6a954ee911..8ca4253ead8b 100644 --- a/src/librustc/middle/trans/controlflow.rs +++ b/src/librustc/middle/trans/controlflow.rs @@ -395,7 +395,7 @@ fn trans_fail_value(bcx: block, let V_filename = PointerCast(bcx, V_filename, Type::i8p()); let args = ~[V_str, V_filename, C_int(ccx, V_line)]; let bcx = callee::trans_lang_call( - bcx, bcx.tcx().lang_items.fail_fn(), args, expr::Ignore); + bcx, bcx.tcx().lang_items.fail_fn(), args, Some(expr::Ignore)).bcx; Unreachable(bcx); return bcx; } @@ -406,7 +406,7 @@ pub fn trans_fail_bounds_check(bcx: block, sp: span, let (filename, line) = filename_and_line_num_from_span(bcx, sp); let args = ~[filename, line, index, len]; let bcx = callee::trans_lang_call( - bcx, bcx.tcx().lang_items.fail_bounds_check_fn(), args, expr::Ignore); + bcx, bcx.tcx().lang_items.fail_bounds_check_fn(), args, Some(expr::Ignore)).bcx; Unreachable(bcx); return bcx; } diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 4cf3873ee706..0180eeb3d220 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -1551,8 +1551,8 @@ fn trans_overloaded_op(bcx: block, origin) }, callee::ArgExprs(args), - dest, - DoAutorefArg) + Some(dest), + DoAutorefArg).bcx } fn int_cast(bcx: block, lldsttype: Type, llsrctype: Type, diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 365681924544..2c505853d5eb 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -789,7 +789,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, bcx = trans_call_inner( bcx, None, fty, ty::mk_nil(), |bcx| Callee {bcx: bcx, data: Closure(datum)}, - ArgVals(arg_vals), Ignore, DontAutorefArg); + ArgVals(arg_vals), Some(Ignore), DontAutorefArg).bcx; } "morestack_addr" => { // XXX This is a hack to grab the address of this particular diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 682a4f133c08..bc493bfa23ec 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -47,7 +47,7 @@ pub fn trans_free(cx: block, v: ValueRef) -> block { callee::trans_lang_call(cx, cx.tcx().lang_items.free_fn(), [PointerCast(cx, v, Type::i8p())], - expr::Ignore) + Some(expr::Ignore)).bcx } pub fn trans_exchange_free(cx: block, v: ValueRef) -> block { @@ -55,7 +55,7 @@ pub fn trans_exchange_free(cx: block, v: ValueRef) -> block { callee::trans_lang_call(cx, cx.tcx().lang_items.exchange_free_fn(), [PointerCast(cx, v, Type::i8p())], - expr::Ignore) + Some(expr::Ignore)).bcx } pub fn take_ty(cx: block, v: ValueRef, t: ty::t) -> block { diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index de91993f345a..cc4111aa1947 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -17,7 +17,6 @@ use middle::trans::callee::{ArgVals, DontAutorefArg}; use middle::trans::callee; use middle::trans::common::*; use middle::trans::datum::*; -use middle::trans::expr::SaveIn; use middle::trans::glue; use middle::trans::machine; use middle::trans::meth; @@ -96,14 +95,13 @@ impl Reflector { ty::mk_bare_fn(tcx, copy self.visitor_methods[mth_idx].fty); let v = self.visitor_val; debug!("passing %u args:", args.len()); - let bcx = self.bcx; + let mut bcx = self.bcx; for args.iter().enumerate().advance |(i, a)| { debug!("arg %u: %s", i, bcx.val_to_str(*a)); } let bool_ty = ty::mk_bool(); - let scratch = scratch_datum(bcx, bool_ty, false); // XXX: Should not be BoxTraitStore! - let bcx = callee::trans_call_inner( + let result = unpack_result!(bcx, callee::trans_call_inner( self.bcx, None, mth_ty, bool_ty, |bcx| meth::trans_trait_callee_from_llval(bcx, mth_ty, @@ -113,8 +111,7 @@ impl Reflector { ast::sty_region( None, ast::m_imm)), - ArgVals(args), SaveIn(scratch.val), DontAutorefArg); - let result = scratch.to_value_llval(bcx); + ArgVals(args), None, DontAutorefArg)); let result = bool_to_i1(bcx, result); let next_bcx = sub_block(bcx, "next"); CondBr(bcx, result, next_bcx.llbb, self.final_bcx.llbb); diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index 809838ded0ab..41dbe320d2d1 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -337,7 +337,7 @@ pub fn trans_uniq_or_managed_vstore(bcx: block, heap: heap, vstore_expr: @ast::e bcx, bcx.tcx().lang_items.strdup_uniq_fn(), [ llptrval, llsizeval ], - expr::SaveIn(lldestval.to_ref_llval(bcx))); + Some(expr::SaveIn(lldestval.to_ref_llval(bcx)))).bcx; return DatumBlock { bcx: bcx, datum: lldestval diff --git a/src/librustc/middle/trans/write_guard.rs b/src/librustc/middle/trans/write_guard.rs index 0db770b6c8bc..bd22e41aff8f 100644 --- a/src/librustc/middle/trans/write_guard.rs +++ b/src/librustc/middle/trans/write_guard.rs @@ -81,7 +81,7 @@ pub fn return_to_mut(mut bcx: block, filename_val, line_val ], - expr::Ignore); + Some(expr::Ignore)).bcx; } callee::trans_lang_call( @@ -93,8 +93,8 @@ pub fn return_to_mut(mut bcx: block, filename_val, line_val ], - expr::Ignore - ) + Some(expr::Ignore) + ).bcx } fn root(datum: &Datum, @@ -144,7 +144,7 @@ fn root(datum: &Datum, let box_ptr = Load(bcx, PointerCast(bcx, scratch.val, Type::i8p().ptr_to())); - bcx = callee::trans_lang_call( + let llresult = unpack_result!(bcx, callee::trans_lang_call( bcx, freeze_did, [ @@ -152,7 +152,7 @@ fn root(datum: &Datum, filename, line ], - expr::SaveIn(scratch_bits.val)); + Some(expr::SaveIn(scratch_bits.val)))); if bcx.tcx().sess.debug_borrows() { bcx = callee::trans_lang_call( @@ -160,11 +160,11 @@ fn root(datum: &Datum, bcx.tcx().lang_items.record_borrow_fn(), [ box_ptr, - Load(bcx, scratch_bits.val), + llresult, filename, line ], - expr::Ignore); + Some(expr::Ignore)).bcx; } add_clean_return_to_mut( @@ -188,5 +188,5 @@ fn perform_write_guard(datum: &Datum, bcx, bcx.tcx().lang_items.check_not_borrowed_fn(), [PointerCast(bcx, llval, Type::i8p()), filename, line], - expr::Ignore) + Some(expr::Ignore)).bcx } From b0a9d8193f121db8115a1010659ee46f7186b2d5 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Mon, 8 Jul 2013 10:25:45 -0700 Subject: [PATCH 93/93] Bump version numbers to 0.8-pre --- Makefile.in | 4 ++-- src/etc/kate/rust.xml | 2 +- src/libextra/extra.rs | 2 +- src/librust/rust.rs | 2 +- src/librustc/front/std_inject.rs | 2 +- src/librustc/front/test.rs | 2 +- src/librustc/rustc.rs | 2 +- src/librustdoc/rustdoc.rs | 2 +- src/librusti/rusti.rs | 2 +- src/librustpkg/rustpkg.rs | 2 +- src/libstd/std.rs | 2 +- src/libsyntax/syntax.rs | 2 +- src/test/run-pass/use.rs | 2 +- 13 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Makefile.in b/Makefile.in index de30113ca4b6..24cd280386af 100644 --- a/Makefile.in +++ b/Makefile.in @@ -139,11 +139,11 @@ endif # version-string calculation CFG_GIT_DIR := $(CFG_SRC_DIR).git -CFG_RELEASE = 0.7 +CFG_RELEASE = 0.8-pre CFG_VERSION = $(CFG_RELEASE) # windows exe's need numeric versions - don't use anything but # numbers and dots here -CFG_VERSION_WIN = 0.7 +CFG_VERSION_WIN = 0.8 ifneq ($(wildcard $(CFG_GIT)),) ifneq ($(wildcard $(CFG_GIT_DIR)),) diff --git a/src/etc/kate/rust.xml b/src/etc/kate/rust.xml index 63f1e50fcaf6..6aa953071476 100644 --- a/src/etc/kate/rust.xml +++ b/src/etc/kate/rust.xml @@ -7,7 +7,7 @@ ]> - + fn diff --git a/src/libextra/extra.rs b/src/libextra/extra.rs index c2d4167074dc..7bec1d600b43 100644 --- a/src/libextra/extra.rs +++ b/src/libextra/extra.rs @@ -21,7 +21,7 @@ Rust extras are part of the standard Rust distribution. */ #[link(name = "extra", - vers = "0.7", + vers = "0.8-pre", uuid = "122bed0b-c19b-4b82-b0b7-7ae8aead7297", url = "https://github.com/mozilla/rust/tree/master/src/libextra")]; diff --git a/src/librust/rust.rs b/src/librust/rust.rs index 63a0ef0842e0..71504b6498bf 100644 --- a/src/librust/rust.rs +++ b/src/librust/rust.rs @@ -13,7 +13,7 @@ // FIXME #2238 Make run only accept source that emits an executable #[link(name = "rust", - vers = "0.7", + vers = "0.8-pre", uuid = "4a24da33-5cc8-4037-9352-2cbe9bd9d27c", url = "https://github.com/mozilla/rust/tree/master/src/rust")]; diff --git a/src/librustc/front/std_inject.rs b/src/librustc/front/std_inject.rs index 699799929ba0..45169a2f6566 100644 --- a/src/librustc/front/std_inject.rs +++ b/src/librustc/front/std_inject.rs @@ -18,7 +18,7 @@ use syntax::codemap::dummy_sp; use syntax::codemap; use syntax::fold; -static STD_VERSION: &'static str = "0.7"; +static STD_VERSION: &'static str = "0.8-pre"; pub fn maybe_inject_libstd_ref(sess: Session, crate: @ast::crate) -> @ast::crate { diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs index f4d89f559f23..7137272acda5 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -273,7 +273,7 @@ mod __test { */ fn mk_std(cx: &TestCtxt) -> ast::view_item { - let vers = ast::lit_str(@"0.7"); + let vers = ast::lit_str(@"0.8-pre"); let vers = nospan(vers); let mi = ast::meta_name_value(@"vers", vers); let mi = nospan(mi); diff --git a/src/librustc/rustc.rs b/src/librustc/rustc.rs index 35375d025ebc..60fc485c4db5 100644 --- a/src/librustc/rustc.rs +++ b/src/librustc/rustc.rs @@ -9,7 +9,7 @@ // except according to those terms. #[link(name = "rustc", - vers = "0.7", + vers = "0.8-pre", uuid = "0ce89b41-2f92-459e-bbc1-8f5fe32f16cf", url = "https://github.com/mozilla/rust/tree/master/src/rustc")]; diff --git a/src/librustdoc/rustdoc.rs b/src/librustdoc/rustdoc.rs index ccf014fb2383..d12f85dcc44f 100644 --- a/src/librustdoc/rustdoc.rs +++ b/src/librustdoc/rustdoc.rs @@ -11,7 +11,7 @@ //! Rustdoc - The Rust documentation generator #[link(name = "rustdoc", - vers = "0.7", + vers = "0.8-pre", uuid = "f8abd014-b281-484d-a0c3-26e3de8e2412", url = "https://github.com/mozilla/rust/tree/master/src/rustdoc")]; diff --git a/src/librusti/rusti.rs b/src/librusti/rusti.rs index 473f2e574791..2ba881f5a04a 100644 --- a/src/librusti/rusti.rs +++ b/src/librusti/rusti.rs @@ -44,7 +44,7 @@ */ #[link(name = "rusti", - vers = "0.7", + vers = "0.8-pre", uuid = "7fb5bf52-7d45-4fee-8325-5ad3311149fc", url = "https://github.com/mozilla/rust/tree/master/src/rusti")]; diff --git a/src/librustpkg/rustpkg.rs b/src/librustpkg/rustpkg.rs index 7c46ba2a8e75..4e4570961e75 100644 --- a/src/librustpkg/rustpkg.rs +++ b/src/librustpkg/rustpkg.rs @@ -11,7 +11,7 @@ // rustpkg - a package manager and build system for Rust #[link(name = "rustpkg", - vers = "0.7", + vers = "0.8-pre", uuid = "25de5e6e-279e-4a20-845c-4cabae92daaf", url = "https://github.com/mozilla/rust/tree/master/src/librustpkg")]; diff --git a/src/libstd/std.rs b/src/libstd/std.rs index f0f3bcdd4e96..8f86216d2407 100644 --- a/src/libstd/std.rs +++ b/src/libstd/std.rs @@ -49,7 +49,7 @@ they contained the following prologue: #[link(name = "std", - vers = "0.7", + vers = "0.8-pre", uuid = "c70c24a7-5551-4f73-8e37-380b11d80be8", url = "https://github.com/mozilla/rust/tree/master/src/libstd")]; diff --git a/src/libsyntax/syntax.rs b/src/libsyntax/syntax.rs index 52ed49ea1ea4..7cb211a402b4 100644 --- a/src/libsyntax/syntax.rs +++ b/src/libsyntax/syntax.rs @@ -14,7 +14,7 @@ */ #[link(name = "syntax", - vers = "0.7", + vers = "0.8-pre", uuid = "9311401b-d6ea-4cd9-a1d9-61f89499c645")]; #[license = "MIT/ASL2"]; diff --git a/src/test/run-pass/use.rs b/src/test/run-pass/use.rs index d73abc803cd5..e23fccb28f15 100644 --- a/src/test/run-pass/use.rs +++ b/src/test/run-pass/use.rs @@ -13,7 +13,7 @@ #[no_std]; extern mod std; extern mod zed(name = "std"); -extern mod bar(name = "std", vers = "0.7"); +extern mod bar(name = "std", vers = "0.8-pre"); use std::str;