diff --git a/.travis.yml b/.travis.yml index a443581b58e..2c2ef693d0b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,10 +39,13 @@ before_script: # manually disables bringing in these two libraries, but the stock LLVM was # apparently built with these options. We provide these options when building so # the `rustc` binary can successfully link. -script: - - make tidy - - RUSTFLAGS="-C link-args='-lffi -lncurses'" make -j4 rustc-stage1 - - make check-stage1-std check-stage1-rpass check-stage1-cfail check-stage1-rfail +# +# As a result of https://github.com/travis-ci/travis-ci/issues/1066, we run +# everything in one large command instead of multiple commands. +script: | + make tidy && + RUSTFLAGS="-C link-args='-lffi -lncurses'" make -j4 rustc-stage1 && + make check-stage1-std check-stage1-rpass check-stage1-cfail check-stage1-rfail env: - NO_BENCH=1 diff --git a/src/README.md b/src/README.md index cc67a3717fa..0ac310df1b8 100644 --- a/src/README.md +++ b/src/README.md @@ -10,6 +10,21 @@ Source layout: | `libgreen/` | The M:N runtime library | | `libnative/` | The 1:1 runtime library | | `libsyntax/` | The Rust parser and pretty-printer | +| `libcollections/` | A collection of useful data structures and containers | +| `libnum/` | Extended number support library (complex, rational, etc) | +| `libtest/` | Rust's test-runner code | +| ------------------- | --------------------------------------------------------- | +| `libarena/` | The arena (a fast but limited) memory allocator | +| `libflate/` | Simple compression library | +| `libfourcc/` | Data format identifier library | +| `libgetopts/` | Get command-line-options library | +| `libglob/` | Unix glob patterns library | +| `libsemver/` | Rust's semantic versioning library | +| `libserialize/` | Encode-Decode types library | +| `libsync/` | Concurrency mechanisms and primitives | +| `libterm/` | ANSI color library for terminals | +| `libtime/` | Time operations library | +| `libuuid/` | UUID's handling code | | ------------------- | --------------------------------------------------------- | | `rt/` | The runtime system | | `rt/rust_*.c` | - Some of the runtime services | @@ -31,8 +46,13 @@ Source layout: | ------------------- | --------------------------------------------------------- | | `librustdoc/` | The Rust API documentation tool | | `libuv/` | The libuv submodule | +| `librustuv/` | Rust libuv support code | | ------------------- | --------------------------------------------------------- | | `llvm/` | The LLVM submodule | | `rustllvm/` | LLVM support code | | ------------------- | --------------------------------------------------------- | | `etc/` | Scripts, editors support, misc | + + +NOTE: This list (especially the second part of the table which contains modules and libraries) +is highly volatile and subject to change. diff --git a/src/doc/tutorial.md b/src/doc/tutorial.md index c2469e0c171..41bf15c0c14 100644 --- a/src/doc/tutorial.md +++ b/src/doc/tutorial.md @@ -1420,8 +1420,8 @@ bad, but often copies are expensive. So we’d like to define a function that takes the points by pointer. We can use references to do this: ~~~ +use std::num::sqrt; # struct Point { x: f64, y: f64 } -# fn sqrt(f: f64) -> f64 { 0.0 } fn compute_distance(p1: &Point, p2: &Point) -> f64 { let x_d = p1.x - p2.x; let y_d = p1.y - p2.y; diff --git a/src/libcollections/hashmap.rs b/src/libcollections/hashmap.rs index 4f0b7dfb35d..7ab85979692 100644 --- a/src/libcollections/hashmap.rs +++ b/src/libcollections/hashmap.rs @@ -53,6 +53,7 @@ //! ``` use std::cmp::max; +use std::default::Default; use std::fmt; use std::hash::{Hash, Hasher, sip}; use std::iter::{FilterMap, Chain, Repeat, Zip}; diff --git a/src/libextra/url.rs b/src/libextra/url.rs index 0292a18817c..5812aaa5038 100644 --- a/src/libextra/url.rs +++ b/src/libextra/url.rs @@ -16,6 +16,7 @@ use std::cmp::Eq; use std::fmt; use std::hash::{Hash, sip}; use std::io::BufReader; +use std::from_str::FromStr; use std::uint; use collections::HashMap; diff --git a/src/libgreen/stack.rs b/src/libgreen/stack.rs index 8a5e6be17c8..053d73c010e 100644 --- a/src/libgreen/stack.rs +++ b/src/libgreen/stack.rs @@ -139,7 +139,7 @@ impl StackPool { pub fn take_stack(&mut self, min_size: uint) -> Stack { // Ideally this would be a binary search match self.stacks.iter().position(|s| min_size <= s.min_size) { - Some(idx) => self.stacks.swap_remove(idx), + Some(idx) => self.stacks.swap_remove(idx).unwrap(), None => Stack::new(min_size) } } diff --git a/src/libnum/bigint.rs b/src/libnum/bigint.rs index 894b3794581..63f48ea9d22 100644 --- a/src/libnum/bigint.rs +++ b/src/libnum/bigint.rs @@ -20,6 +20,7 @@ use Integer; use std::cmp; use std::fmt; +use std::from_str::FromStr; use std::num::{Bitwise, ToPrimitive, FromPrimitive}; use std::num::{Zero, One, ToStrRadix, FromStrRadix}; use std::rand::Rng; @@ -1397,8 +1398,9 @@ mod biguint_tests { use super::{Plus, BigInt, RandBigInt, ToBigInt}; use std::cmp::{Less, Equal, Greater}; + use std::from_str::FromStr; use std::i64; - use std::num::{Zero, One, FromStrRadix}; + use std::num::{Zero, One, FromStrRadix, ToStrRadix}; use std::num::{ToPrimitive, FromPrimitive}; use std::rand::{task_rng}; use std::str; @@ -2056,7 +2058,7 @@ mod bigint_tests { use std::cmp::{Less, Equal, Greater}; use std::i64; - use std::num::{Zero, One, FromStrRadix}; + use std::num::{Zero, One, FromStrRadix, ToStrRadix}; use std::num::{ToPrimitive, FromPrimitive}; use std::rand::{task_rng}; use std::u64; diff --git a/src/libnum/rational.rs b/src/libnum/rational.rs index 44a916c5d4e..79ff54cb90c 100644 --- a/src/libnum/rational.rs +++ b/src/libnum/rational.rs @@ -333,7 +333,7 @@ impl mod test { use super::{Ratio, Rational, BigRational}; - use std::num::{Zero,One,FromStrRadix,FromPrimitive}; + use std::num::{Zero, One, FromStrRadix, FromPrimitive, ToStrRadix}; use std::from_str::FromStr; pub static _0 : Rational = Ratio { numer: 0, denom: 1}; diff --git a/src/librustc/back/archive.rs b/src/librustc/back/archive.rs index 1df34576c3e..e0c570664fe 100644 --- a/src/librustc/back/archive.rs +++ b/src/librustc/back/archive.rs @@ -145,7 +145,10 @@ impl Archive { /// Lists all files in an archive pub fn files(&self) -> ~[~str] { let output = run_ar(self.sess, "t", None, [&self.dst]); - str::from_utf8(output.output).unwrap().lines().map(|s| s.to_owned()).collect() + let output = str::from_utf8(output.output).unwrap(); + // use lines_any because windows delimits output with `\r\n` instead of + // just `\n` + output.lines_any().map(|s| s.to_owned()).collect() } fn add_archive(&mut self, archive: &Path, name: &str, diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index e7d97f03913..1f5b76953dc 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -67,6 +67,18 @@ pub struct ArchiveMetadata { priv data: &'static [u8], } +// FIXME(#11857) this should be a "real" realpath +fn realpath(p: &Path) -> Path { + use std::os; + use std::io::fs; + + let path = os::make_absolute(p); + match fs::readlink(&path) { + Ok(p) => p, + Err(..) => path + } +} + impl Context { pub fn load_library_crate(&self, root_ident: Option<~str>) -> Library { match self.find_library_crate() { @@ -121,7 +133,7 @@ impl Context { (HashSet::new(), HashSet::new()) }); let (ref mut rlibs, _) = *slot; - rlibs.insert(path.clone()); + rlibs.insert(realpath(path)); FileMatches } None => { @@ -138,7 +150,7 @@ impl Context { (HashSet::new(), HashSet::new()) }); let (_, ref mut dylibs) = *slot; - dylibs.insert(path.clone()); + dylibs.insert(realpath(path)); FileMatches } None => { diff --git a/src/librustc/middle/borrowck/gather_loans/mod.rs b/src/librustc/middle/borrowck/gather_loans/mod.rs index 15922d57ba8..263ed47b29e 100644 --- a/src/librustc/middle/borrowck/gather_loans/mod.rs +++ b/src/librustc/middle/borrowck/gather_loans/mod.rs @@ -160,16 +160,8 @@ fn gather_loans_in_local(this: &mut GatherLoanCtxt, }) } Some(init) => { - // Variable declarations with initializers are considered "assigns": - let tcx = this.bccx.tcx; - pat_util::pat_bindings(tcx.def_map, local.pat, |_, id, span, _| { - gather_moves::gather_assignment(this.bccx, - &this.move_data, - id, - span, - @LpVar(id), - id); - }); + // Variable declarations with initializers are considered "assigns", + // which is handled by `gather_pat`: let init_cmt = this.bccx.cat_expr(init); this.gather_pat(init_cmt, local.pat, None); } @@ -811,6 +803,17 @@ impl<'a> GatherLoanCtxt<'a> { self.bccx.cat_pattern(discr_cmt, root_pat, |cmt, pat| { match pat.node { ast::PatIdent(bm, _, _) if self.pat_is_binding(pat) => { + // Each match binding is effectively an assignment. + let tcx = self.bccx.tcx; + pat_util::pat_bindings(tcx.def_map, pat, |_, id, span, _| { + gather_moves::gather_assignment(self.bccx, + &self.move_data, + id, + span, + @LpVar(id), + id); + }); + match bm { ast::BindByRef(mutbl) => { // ref x or ref x @ p --- creates a ptr which must diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 5b3c18a5a93..5df6c231b5c 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -282,6 +282,7 @@ pub fn decl_rust_fn(ccx: &CrateContext, has_env: bool, if !type_is_immediate(ccx, arg_ty) { unsafe { llvm::LLVMAddAttribute(llarg, lib::llvm::NoAliasAttribute as c_uint); + llvm::LLVMAddAttribute(llarg, lib::llvm::NoCaptureAttribute as c_uint); } } } diff --git a/src/libstd/bool.rs b/src/libstd/bool.rs index 918d42e1bce..2376603fcc8 100644 --- a/src/libstd/bool.rs +++ b/src/libstd/bool.rs @@ -295,6 +295,7 @@ impl Default for bool { mod tests { use prelude::*; use super::all_values; + use from_str::FromStr; #[test] fn test_bool() { diff --git a/src/libstd/io/net/ip.rs b/src/libstd/io/net/ip.rs index e4f36764323..f67ba8fce03 100644 --- a/src/libstd/io/net/ip.rs +++ b/src/libstd/io/net/ip.rs @@ -340,6 +340,7 @@ impl FromStr for SocketAddr { mod test { use prelude::*; use super::*; + use from_str::FromStr; #[test] fn test_from_str_ipv4() { diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index a98fd31c457..a686edef99e 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -15,6 +15,7 @@ use prelude::*; use cmath; use default::Default; +use from_str::FromStr; use libc::{c_float, c_int}; use num::{FPCategory, FPNaN, FPInfinite , FPZero, FPSubnormal, FPNormal}; use num::{Zero, One, Bounded, strconv}; diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index 5975ce40d84..026bd651e0e 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -16,6 +16,7 @@ use prelude::*; use cmath; use default::Default; +use from_str::FromStr; use libc::{c_double, c_int}; use num::{FPCategory, FPNaN, FPInfinite , FPZero, FPSubnormal, FPNormal}; use num::{Zero, One, Bounded, strconv}; diff --git a/src/libstd/num/i16.rs b/src/libstd/num/i16.rs index 141626ed98a..0ecb55e5106 100644 --- a/src/libstd/num/i16.rs +++ b/src/libstd/num/i16.rs @@ -15,6 +15,7 @@ use prelude::*; use default::Default; +use from_str::FromStr; use num::{Bitwise, Bounded, CheckedAdd, CheckedSub, CheckedMul}; use num::{CheckedDiv, Zero, One, strconv}; use num::{ToStrRadix, FromStrRadix}; diff --git a/src/libstd/num/i32.rs b/src/libstd/num/i32.rs index a43a6e6a288..0526f2c488b 100644 --- a/src/libstd/num/i32.rs +++ b/src/libstd/num/i32.rs @@ -15,6 +15,7 @@ use prelude::*; use default::Default; +use from_str::FromStr; use num::{Bitwise, Bounded, CheckedAdd, CheckedSub, CheckedMul}; use num::{CheckedDiv, Zero, One, strconv}; use num::{ToStrRadix, FromStrRadix}; diff --git a/src/libstd/num/i64.rs b/src/libstd/num/i64.rs index e8503d808a7..0c1c01dbf4a 100644 --- a/src/libstd/num/i64.rs +++ b/src/libstd/num/i64.rs @@ -15,6 +15,7 @@ use prelude::*; use default::Default; +use from_str::FromStr; #[cfg(target_word_size = "64")] use num::CheckedMul; use num::{Bitwise, Bounded, CheckedAdd, CheckedSub}; diff --git a/src/libstd/num/i8.rs b/src/libstd/num/i8.rs index 9f857ff40ff..881cc46201e 100644 --- a/src/libstd/num/i8.rs +++ b/src/libstd/num/i8.rs @@ -15,6 +15,7 @@ use prelude::*; use default::Default; +use from_str::FromStr; use num::{Bitwise, Bounded, CheckedAdd, CheckedSub, CheckedMul}; use num::{CheckedDiv, Zero, One, strconv}; use num::{ToStrRadix, FromStrRadix}; diff --git a/src/libstd/num/int.rs b/src/libstd/num/int.rs index 6d1a50b724f..83c9e8ea855 100644 --- a/src/libstd/num/int.rs +++ b/src/libstd/num/int.rs @@ -15,6 +15,7 @@ use prelude::*; use default::Default; +use from_str::FromStr; use num::{Bitwise, Bounded, CheckedAdd, CheckedSub, CheckedMul}; use num::{CheckedDiv, Zero, One, strconv}; use num::{ToStrRadix, FromStrRadix}; diff --git a/src/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs index 030aa2d81fa..ea62a3ec374 100644 --- a/src/libstd/num/int_macros.rs +++ b/src/libstd/num/int_macros.rs @@ -295,8 +295,9 @@ mod tests { use int; use i32; use num; - use num::CheckedDiv; use num::Bitwise; + use num::CheckedDiv; + use num::ToStrRadix; #[test] fn test_overflows() { diff --git a/src/libstd/num/u16.rs b/src/libstd/num/u16.rs index da0293b3418..d1de1ff0a72 100644 --- a/src/libstd/num/u16.rs +++ b/src/libstd/num/u16.rs @@ -15,6 +15,7 @@ use prelude::*; use default::Default; +use from_str::FromStr; use num::{Bitwise, Bounded}; use num::{CheckedAdd, CheckedSub, CheckedMul}; use num::{CheckedDiv, Zero, One, strconv}; diff --git a/src/libstd/num/u32.rs b/src/libstd/num/u32.rs index b103e18f701..1caec678025 100644 --- a/src/libstd/num/u32.rs +++ b/src/libstd/num/u32.rs @@ -15,6 +15,7 @@ use prelude::*; use default::Default; +use from_str::FromStr; use num::{Bitwise, Bounded}; use num::{CheckedAdd, CheckedSub, CheckedMul}; use num::{CheckedDiv, Zero, One, strconv}; diff --git a/src/libstd/num/u64.rs b/src/libstd/num/u64.rs index f7956f0128e..ab495834eaa 100644 --- a/src/libstd/num/u64.rs +++ b/src/libstd/num/u64.rs @@ -15,6 +15,7 @@ use prelude::*; use default::Default; +use from_str::FromStr; use num::{Bitwise, Bounded}; #[cfg(target_word_size = "64")] use num::CheckedMul; diff --git a/src/libstd/num/u8.rs b/src/libstd/num/u8.rs index e6ce9c72e96..a0ef574f6cf 100644 --- a/src/libstd/num/u8.rs +++ b/src/libstd/num/u8.rs @@ -15,6 +15,7 @@ use prelude::*; use default::Default; +use from_str::FromStr; use num::{Bitwise, Bounded}; use num::{CheckedAdd, CheckedSub, CheckedMul}; use num::{CheckedDiv, Zero, One, strconv}; diff --git a/src/libstd/num/uint.rs b/src/libstd/num/uint.rs index a8c85787f7e..95d4a3a50be 100644 --- a/src/libstd/num/uint.rs +++ b/src/libstd/num/uint.rs @@ -15,6 +15,7 @@ use prelude::*; use default::Default; +use from_str::FromStr; use num::{Bitwise, Bounded}; use num::{CheckedAdd, CheckedSub, CheckedMul}; use num::{CheckedDiv, Zero, One, strconv}; diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs index 001927e6033..719afeb7878 100644 --- a/src/libstd/num/uint_macros.rs +++ b/src/libstd/num/uint_macros.rs @@ -233,6 +233,7 @@ mod tests { use num; use num::CheckedDiv; use num::Bitwise; + use num::ToStrRadix; use u16; #[test] diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index ce746852dae..cc1a14a4f82 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -43,14 +43,12 @@ pub use char::Char; pub use clone::{Clone, DeepClone}; pub use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater, Equiv}; pub use container::{Container, Mutable, Map, MutableMap, Set, MutableSet}; -pub use default::Default; -pub use from_str::FromStr; pub use iter::{FromIterator, Extendable}; pub use iter::{Iterator, DoubleEndedIterator, RandomAccessIterator, CloneableIterator}; pub use iter::{OrdIterator, MutableDoubleEndedIterator, ExactSize}; pub use num::{Num, NumCast, CheckedAdd, CheckedSub, CheckedMul}; pub use num::{Signed, Unsigned, Round}; -pub use num::{Primitive, Int, Float, ToStrRadix, ToPrimitive, FromPrimitive}; +pub use num::{Primitive, Int, Float, ToPrimitive, FromPrimitive}; pub use path::{GenericPath, Path, PosixPath, WindowsPath}; pub use ptr::RawPtr; pub use io::{Buffer, Writer, Reader, Seek}; diff --git a/src/libstd/rand/reseeding.rs b/src/libstd/rand/reseeding.rs index 758ca22e5c3..a916ce173fb 100644 --- a/src/libstd/rand/reseeding.rs +++ b/src/libstd/rand/reseeding.rs @@ -144,6 +144,7 @@ impl Default for ReseedWithDefault { mod test { use prelude::*; use super::*; + use default::Default; use rand::{SeedableRng, Rng}; struct Counter { diff --git a/src/libstd/str.rs b/src/libstd/str.rs index daaf46be187..12044b4a06a 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -3072,6 +3072,7 @@ impl Default for ~str { #[cfg(test)] mod tests { use iter::AdditiveIterator; + use default::Default; use prelude::*; use str::*; diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index d8cb8bf3ed1..cf49ea53562 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -1368,13 +1368,24 @@ pub trait OwnedVector { /// ``` fn remove(&mut self, i: uint) -> Option; - /** - * Remove an element from anywhere in the vector and return it, replacing it - * with the last element. This does not preserve ordering, but is O(1). - * - * Fails if index >= length. - */ - fn swap_remove(&mut self, index: uint) -> T; + /// Remove an element from anywhere in the vector and return it, replacing it + /// with the last element. This does not preserve ordering, but is O(1). + /// + /// Returns `None` if `index` is out of bounds. + /// + /// # Example + /// ```rust + /// let mut v = ~[~"foo", ~"bar", ~"baz", ~"qux"]; + /// + /// assert_eq!(v.swap_remove(1), Some(~"bar")); + /// assert_eq!(v, ~[~"foo", ~"qux", ~"baz"]); + /// + /// assert_eq!(v.swap_remove(0), Some(~"foo")); + /// assert_eq!(v, ~[~"baz", ~"qux"]); + /// + /// assert_eq!(v.swap_remove(2), None); + /// ``` + fn swap_remove(&mut self, index: uint) -> Option; /// Shorten a vector, dropping excess elements. fn truncate(&mut self, newlen: uint); @@ -1580,15 +1591,14 @@ impl OwnedVector for ~[T] { None } } - fn swap_remove(&mut self, index: uint) -> T { + fn swap_remove(&mut self, index: uint) -> Option { let ln = self.len(); - if index >= ln { - fail!("vec::swap_remove - index {} >= length {}", index, ln); - } if index < ln - 1 { self.swap(index, ln - 1); + } else if index >= ln { + return None } - self.pop().unwrap() + self.pop() } fn truncate(&mut self, newlen: uint) { let oldlen = self.len(); @@ -3194,15 +3204,15 @@ mod tests { fn test_swap_remove() { let mut v = ~[1, 2, 3, 4, 5]; let mut e = v.swap_remove(0); - assert_eq!(v.len(), 4); - assert_eq!(e, 1); - assert_eq!(v[0], 5); + assert_eq!(e, Some(1)); + assert_eq!(v, ~[5, 2, 3, 4]); e = v.swap_remove(3); - assert_eq!(v.len(), 3); - assert_eq!(e, 4); - assert_eq!(v[0], 5); - assert_eq!(v[1], 2); - assert_eq!(v[2], 3); + assert_eq!(e, Some(4)); + assert_eq!(v, ~[5, 2, 3]); + + e = v.swap_remove(3); + assert_eq!(e, None); + assert_eq!(v, ~[5, 2, 3]); } #[test] diff --git a/src/libstd/vec_ng.rs b/src/libstd/vec_ng.rs index 3532e7b26a4..52d3405f8c1 100644 --- a/src/libstd/vec_ng.rs +++ b/src/libstd/vec_ng.rs @@ -18,6 +18,7 @@ use container::Container; use iter::{DoubleEndedIterator, FromIterator, Iterator}; use libc::{free, c_void}; use mem::{size_of, move_val_init}; +use num; use num::CheckedMul; use ops::Drop; use option::{None, Option, Some}; @@ -136,6 +137,12 @@ impl Vec { self.cap } + pub fn reserve(&mut self, capacity: uint) { + if capacity >= self.len { + self.reserve_exact(num::next_power_of_two(capacity)) + } + } + pub fn reserve_exact(&mut self, capacity: uint) { if capacity >= self.len { let size = capacity.checked_mul(&size_of::()).expect("capacity overflow"); @@ -277,15 +284,14 @@ impl Vec { } #[inline] - pub fn swap_remove(&mut self, index: uint) -> T { + pub fn swap_remove(&mut self, index: uint) -> Option { let length = self.len(); - if index >= length { - fail!("Vec::swap_remove - index {} >= length {}", index, length); - } if index < length - 1 { self.as_mut_slice().swap(index, length - 1); + } else if index >= length { + return None } - self.pop().unwrap() + self.pop() } #[inline] @@ -297,7 +303,7 @@ impl Vec { let len = self.len(); assert!(index <= len); // space for the new element - self.reserve_exact(len + 1); + self.reserve(len + 1); unsafe { // infallible // The spot to put the new value @@ -392,4 +398,3 @@ impl Drop for MoveItems { } } } - diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 83700e390cb..a67d1b933a8 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -460,11 +460,12 @@ impl CodeMap { for mbc in multibyte_chars.get().iter() { debug!("codemap: {:?}-byte char at {:?}", mbc.bytes, mbc.pos); if mbc.pos < bpos { - total_extra_bytes += mbc.bytes; + // every character is at least one byte, so we only + // count the actual extra bytes. + total_extra_bytes += mbc.bytes - 1; // We should never see a byte position in the middle of a // character - assert!(bpos == mbc.pos || - bpos.to_uint() >= mbc.pos.to_uint() + mbc.bytes); + assert!(bpos.to_uint() >= mbc.pos.to_uint() + mbc.bytes); } else { break; } diff --git a/src/libsyntax/crateid.rs b/src/libsyntax/crateid.rs index 2417a6fa1ba..659cd13c94d 100644 --- a/src/libsyntax/crateid.rs +++ b/src/libsyntax/crateid.rs @@ -17,6 +17,9 @@ use std::fmt; /// `1.0`. If no crate name is given after the hash, the name is inferred to /// be the last component of the path. If no version is given, it is inferred /// to be `0.0`. + +use std::from_str::FromStr; + #[deriving(Clone, Eq)] pub struct CrateId { /// A path which represents the codes origin. By convention this is the diff --git a/src/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs index 3abd411a003..325df0ba777 100644 --- a/src/libsyntax/opt_vec.rs +++ b/src/libsyntax/opt_vec.rs @@ -16,6 +16,7 @@ */ use std::vec; +use std::default::Default; #[deriving(Clone, Encodable, Decodable, Hash)] pub enum OptVec { diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index b711e95bc94..5bace75a5ea 100644 --- a/src/libsyntax/parse/lexer.rs +++ b/src/libsyntax/parse/lexer.rs @@ -264,8 +264,7 @@ pub fn bump(rdr: &StringReader) { } if byte_offset_diff > 1 { - rdr.filemap.record_multibyte_char( - Pos::from_uint(current_byte_offset), byte_offset_diff); + rdr.filemap.record_multibyte_char(rdr.last_pos.get(), byte_offset_diff); } } else { rdr.curr.set(None); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index dac668da343..cbe371a06a5 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3185,15 +3185,35 @@ impl Parser { let pth = self.parse_path(NoTypesAllowed).path; self.bump(); - let id = if self.token == token::LPAREN { + let id = if self.token == token::LPAREN || self.token == token::LBRACE { token::special_idents::invalid // no special identifier } else { self.parse_ident() }; + // check that we're pointing at delimiters (need to check + // again after the `if`, because of `parse_ident` + // consuming more tokens). + let (bra, ket) = match self.token { + token::LPAREN => (token::LPAREN, token::RPAREN), + token::LBRACE => (token::LBRACE, token::RBRACE), + _ => { + // we only expect an ident if we didn't parse one + // above. + let ident_str = if id == token::special_idents::invalid { + "identifier, " + } else { + "" + }; + let tok_str = self.this_token_to_str(); + self.fatal(format!("expected {}`(` or `\\{`, but found `{}`", + ident_str, tok_str)) + } + }; + let tts = self.parse_unspanned_seq( - &token::LPAREN, - &token::RPAREN, + &bra, + &ket, seq_sep_none(), |p| p.parse_token_tree() ); diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 6093948d9f4..02950c07582 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -41,6 +41,7 @@ use term::color::{Color, RED, YELLOW, GREEN, CYAN}; use std::cmp; use std::f64; use std::fmt; +use std::from_str::FromStr; use std::io::stdio::StdWriter; use std::io::{File, PortReader, ChanWriter}; use std::io; diff --git a/src/libuuid/lib.rs b/src/libuuid/lib.rs index 7a3ed09a492..8dbdedc1848 100644 --- a/src/libuuid/lib.rs +++ b/src/libuuid/lib.rs @@ -66,7 +66,9 @@ extern crate serialize; use std::cast::{transmute,transmute_copy}; use std::char::Char; +use std::default::Default; use std::fmt; +use std::from_str::FromStr; use std::hash::{Hash, sip}; use std::num::FromStrRadix; use std::rand::Rng; diff --git a/src/test/bench/shootout-threadring.rs b/src/test/bench/shootout-threadring.rs index 7063194eab8..6ce6fb503a1 100644 --- a/src/test/bench/shootout-threadring.rs +++ b/src/test/bench/shootout-threadring.rs @@ -55,6 +55,8 @@ fn roundtrip(id: int, n_tasks: int, p: &Port, ch: &Chan) { } fn main() { + use std::from_str::FromStr; + let args = if os::getenv("RUST_BENCH").is_some() { ~[~"", ~"2000000", ~"503"] } diff --git a/src/test/compile-fail/borrowck-match-binding-is-assignment.rs b/src/test/compile-fail/borrowck-match-binding-is-assignment.rs new file mode 100644 index 00000000000..72d9afd4d2b --- /dev/null +++ b/src/test/compile-fail/borrowck-match-binding-is-assignment.rs @@ -0,0 +1,51 @@ +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that immutable pattern bindings cannot be reassigned. + +enum E { + Foo(int) +} + +struct S { + bar: int, +} + +pub fn main() { + match 1i { + x => { + x += 1; //~ ERROR re-assignment of immutable variable `x` + } + } + + match Foo(1) { + Foo(x) => { + x += 1; //~ ERROR re-assignment of immutable variable `x` + } + } + + match S { bar: 1 } { + S { bar: x } => { + x += 1; //~ ERROR re-assignment of immutable variable `x` + } + } + + match (1i,) { + (x,) => { + x += 1; //~ ERROR re-assignment of immutable variable `x` + } + } + + match [1,2,3] { + [x,_,_] => { + x += 1; //~ ERROR re-assignment of immutable variable `x` + } + } +} diff --git a/src/test/compile-fail/issue-1451.rs b/src/test/compile-fail/issue-9814.rs similarity index 53% rename from src/test/compile-fail/issue-1451.rs rename to src/test/compile-fail/issue-9814.rs index ce27cc3be38..f7609a767a7 100644 --- a/src/test/compile-fail/issue-1451.rs +++ b/src/test/compile-fail/issue-9814.rs @@ -1,4 +1,4 @@ -// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,26 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-test +// Verify that single-variant enums cant be de-referenced +// Regression test for issue #9814 -struct T { f: extern "Rust" fn() }; -struct S { f: extern "Rust" fn() }; - -fn fooS(t: S) { -} - -fn fooT(t: T) { -} - -fn bar() { -} +enum Foo { Bar(int) } fn main() { - let x: extern "Rust" fn() = bar; - fooS(S {f: x}); - fooS(S {f: bar}); - - let x: extern "Rust" fn() = bar; - fooT(T {f: x}); - fooT(T {f: bar}); + let _ = *Bar(2); //~ ERROR type `Foo` cannot be dereferenced } diff --git a/src/test/compile-fail/macro-bad-delimiter-ident.rs b/src/test/compile-fail/macro-bad-delimiter-ident.rs new file mode 100644 index 00000000000..6f3b8bd421f --- /dev/null +++ b/src/test/compile-fail/macro-bad-delimiter-ident.rs @@ -0,0 +1,13 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + foo! bar < //~ ERROR expected `(` or `{`, but found `<` +} diff --git a/src/test/compile-fail/macro-mismatched-delim-brace-paren.rs b/src/test/compile-fail/macro-mismatched-delim-brace-paren.rs new file mode 100644 index 00000000000..d03698c1573 --- /dev/null +++ b/src/test/compile-fail/macro-mismatched-delim-brace-paren.rs @@ -0,0 +1,15 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + foo! { + bar, "baz", 1, 2.0 + ) //~ ERROR incorrect close delimiter +} diff --git a/src/test/compile-fail/macro-mismatched-delim-paren-brace.rs b/src/test/compile-fail/macro-mismatched-delim-paren-brace.rs new file mode 100644 index 00000000000..d80f93d7ad0 --- /dev/null +++ b/src/test/compile-fail/macro-mismatched-delim-paren-brace.rs @@ -0,0 +1,15 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + foo! ( + bar, "baz", 1, 2.0 + } //~ ERROR incorrect close delimiter +} diff --git a/src/test/compile-fail/vec-add.rs b/src/test/compile-fail/vec-add.rs deleted file mode 100644 index 3f1b82d1768..00000000000 --- a/src/test/compile-fail/vec-add.rs +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// ignore-test - -// FIXME (Issue #2711): + should allow immutable or mutable vectors on -// the right hand side in all cases. We are getting compiler errors -// about this now, so I'm ignoring the test for now. -eholk - -fn add(i: ~[int], mut m: ~[int]) { - - // Check that: - // (1) vectors of any two mutabilities can be added - // (2) result has mutability of lhs - - add(i + ~[3], - m + ~[3], - ~[3]); - - add(i + ~[3], - m + ~[3], - ~[3]); - - add(i + i, - m + i, - i); - - add(i + m, - m + m, - m); - - add(m + ~[3], //~ ERROR mismatched types - m + ~[3], - m + ~[3]); - - add(i + ~[3], - i + ~[3], //~ ERROR mismatched types - i + ~[3]); - - add(m + ~[3], //~ ERROR mismatched types - m + ~[3], - m + ~[3]); - - add(i + ~[3], - i + ~[3], //~ ERROR mismatched types - i + ~[3]); - - add(m + i, //~ ERROR mismatched types - m + i, - m + i); - - add(i + i, - i + i, //~ ERROR mismatched types - i + i); - - add(m + m, //~ ERROR mismatched types - m + m, - m + m); - - add(i + m, - i + m, //~ ERROR mismatched types - i + m); -} - -fn main() { -} diff --git a/src/test/run-make/symlinked-libraries/Makefile b/src/test/run-make/symlinked-libraries/Makefile new file mode 100644 index 00000000000..45ef241c28f --- /dev/null +++ b/src/test/run-make/symlinked-libraries/Makefile @@ -0,0 +1,7 @@ +-include ../tools.mk + +all: + $(RUSTC) foo.rs + mkdir -p $(TMPDIR)/other + ln -nsf $(TMPDIR)/$(call DYLIB_GLOB,foo) $(TMPDIR)/other + $(RUSTC) bar.rs -L $(TMPDIR)/other diff --git a/src/test/compile-fail/issue-2074.rs b/src/test/run-make/symlinked-libraries/bar.rs similarity index 71% rename from src/test/compile-fail/issue-2074.rs rename to src/test/run-make/symlinked-libraries/bar.rs index 338d0cb439c..73596f93f56 100644 --- a/src/test/compile-fail/issue-2074.rs +++ b/src/test/run-make/symlinked-libraries/bar.rs @@ -8,16 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-test +extern crate foo; fn main() { - let one: || -> uint = || { - enum r { a }; - a as uint - }; - let two = || -> uint = || { - enum r { a }; - a as uint - }; - one(); two(); + foo::bar(); } diff --git a/src/test/compile-fail/omitted-arg-wrong-types.rs b/src/test/run-make/symlinked-libraries/foo.rs similarity index 65% rename from src/test/compile-fail/omitted-arg-wrong-types.rs rename to src/test/run-make/symlinked-libraries/foo.rs index 1f1a6849aca..9fbe36f0376 100644 --- a/src/test/compile-fail/omitted-arg-wrong-types.rs +++ b/src/test/run-make/symlinked-libraries/foo.rs @@ -8,14 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-test - #2093 +#[crate_type = "dylib"]; -fn let_in(x: T, f: |T|) {} - -fn main() { - let_in(3u, |i| { assert!(i == 3); }); - //~^ ERROR expected `uint` but found `int` - - let_in(3, |i| { assert!(i == 3u); }); - //~^ ERROR expected `int` but found `uint` -} +pub fn bar() {} diff --git a/src/test/run-make/unicode-input/Makefile b/src/test/run-make/unicode-input/Makefile new file mode 100644 index 00000000000..2d6ecd3c55e --- /dev/null +++ b/src/test/run-make/unicode-input/Makefile @@ -0,0 +1,11 @@ +-include ../tools.mk + +all: + # check that we don't ICE on unicode input, issue #11178 + $(RUSTC) multiple_files.rs + $(call RUN,multiple_files) "$(RUSTC)" "$(TMPDIR)" + + # check that our multibyte-ident spans are (approximately) the + # correct length. issue #8706 + $(RUSTC) span_length.rs + $(call RUN,span_length) "$(RUSTC)" "$(TMPDIR)" diff --git a/src/test/run-make/unicode-input/multiple_files.rs b/src/test/run-make/unicode-input/multiple_files.rs new file mode 100644 index 00000000000..80371aa9840 --- /dev/null +++ b/src/test/run-make/unicode-input/multiple_files.rs @@ -0,0 +1,65 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::{char, os, str}; +use std::rand::{task_rng, Rng}; +use std::io::{File, Process}; + +// creates unicode_input_multiple_files_{main,chars}.rs, where the +// former imports the latter. `_chars` just contains an indentifier +// made up of random characters, because will emit an error message +// about the ident being in the wrong place, with a span (and creating +// this span used to upset the compiler). + +fn random_char() -> char { + let mut rng = task_rng(); + // a subset of the XID_start unicode table (ensuring that the + // compiler doesn't fail with an "unrecognised token" error) + let (lo, hi): (u32, u32) = match rng.gen_range(1, 4 + 1) { + 1 => (0x41, 0x5a), + 2 => (0xf8, 0x1ba), + 3 => (0x1401, 0x166c), + _ => (0x10400, 0x1044f) + }; + + char::from_u32(rng.gen_range(lo, hi + 1)).unwrap() +} + +fn main() { + let args = os::args(); + let rustc = args[1].as_slice(); + let tmpdir = Path::new(args[2].as_slice()); + + let main_file = tmpdir.join("unicode_input_multiple_files_main.rs"); + let main_file_str = main_file.as_str().unwrap(); + { + let _ = File::create(&main_file).unwrap() + .write_str("mod unicode_input_multiple_files_chars;"); + } + + for _ in range(0, 100) { + { + let randoms = tmpdir.join("unicode_input_multiple_files_chars.rs"); + let mut w = File::create(&randoms).unwrap(); + for _ in range(0, 30) { + let _ = w.write_char(random_char()); + } + } + + // rustc is passed to us with --out-dir and -L etc., so we + // can't exec it directly + let result = Process::output("sh", [~"-c", rustc + " " + main_file_str]).unwrap(); + let err = str::from_utf8_lossy(result.error); + + // positive test so that this test will be updated when the + // compiler changes. + assert!(err.as_slice().contains("expected item but found")) + } +} diff --git a/src/test/run-make/unicode-input/span_length.rs b/src/test/run-make/unicode-input/span_length.rs new file mode 100644 index 00000000000..3227f672bcd --- /dev/null +++ b/src/test/run-make/unicode-input/span_length.rs @@ -0,0 +1,62 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::{char, os, str}; +use std::rand::{task_rng, Rng}; +use std::io::{File, Process}; + +// creates a file with `fn main() { }` and checks the +// compiler emits a span of the appropriate length (for the +// "unresolved name" message); currently just using the number of code +// points, but should be the number of graphemes (FIXME #7043) + +fn random_char() -> char { + let mut rng = task_rng(); + // a subset of the XID_start unicode table (ensuring that the + // compiler doesn't fail with an "unrecognised token" error) + let (lo, hi): (u32, u32) = match rng.gen_range(1, 4 + 1) { + 1 => (0x41, 0x5a), + 2 => (0xf8, 0x1ba), + 3 => (0x1401, 0x166c), + _ => (0x10400, 0x1044f) + }; + + char::from_u32(rng.gen_range(lo, hi + 1)).unwrap() +} + +fn main() { + let args = os::args(); + let rustc = args[1].as_slice(); + let tmpdir = Path::new(args[2].as_slice()); + + let main_file = tmpdir.join("span_main.rs"); + let main_file_str = main_file.as_str().unwrap(); + + for _ in range(0, 100) { + let n = task_rng().gen_range(3u, 20); + + { + let _ = write!(&mut File::create(&main_file).unwrap(), + r"\#[feature(non_ascii_idents)]; fn main() \{ {} \}", + // random string of length n + range(0, n).map(|_| random_char()).collect::<~str>()); + } + + // rustc is passed to us with --out-dir and -L etc., so we + // can't exec it directly + let result = Process::output("sh", [~"-c", rustc + " " + main_file_str]).unwrap(); + + let err = str::from_utf8_lossy(result.error); + + // the span should end the line (e.g no extra ~'s) + let expected_span = "^" + "~".repeat(n - 1) + "\n"; + assert!(err.as_slice().contains(expected_span)); + } +} diff --git a/src/test/run-pass/macro-with-braces-in-expr-position.rs b/src/test/run-pass/macro-with-braces-in-expr-position.rs new file mode 100644 index 00000000000..2a368568f8c --- /dev/null +++ b/src/test/run-pass/macro-with-braces-in-expr-position.rs @@ -0,0 +1,28 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[feature(macro_rules)]; + +macro_rules! expr (($e: expr) => { $e }) + +macro_rules! spawn { + ($($code: tt)*) => { + expr!(spawn(proc() {$($code)*})) + } +} + +pub fn main() { + spawn! { + info!("stmt"); + }; + let _ = spawn! { + info!("expr"); + }; +}