From 8922fa01228f5161aa0ebd714f86f2712a3c7ea8 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 22 Feb 2014 10:45:44 -0800 Subject: [PATCH 01/18] rustc: Don't error on the rlib symlinks This commit implements a layman's version of realpath() for metadata::loader to use in order to not error on symlinks pointing to the same file. Closes #12459 --- src/librustc/metadata/loader.rs | 16 ++++++++++++++-- src/test/run-make/symlinked-libraries/Makefile | 7 +++++++ src/test/run-make/symlinked-libraries/bar.rs | 15 +++++++++++++++ src/test/run-make/symlinked-libraries/foo.rs | 13 +++++++++++++ 4 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 src/test/run-make/symlinked-libraries/Makefile create mode 100644 src/test/run-make/symlinked-libraries/bar.rs create mode 100644 src/test/run-make/symlinked-libraries/foo.rs diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index e7d97f03913b0..1f5b76953dcde 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/test/run-make/symlinked-libraries/Makefile b/src/test/run-make/symlinked-libraries/Makefile new file mode 100644 index 0000000000000..45ef241c28f7f --- /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/run-make/symlinked-libraries/bar.rs b/src/test/run-make/symlinked-libraries/bar.rs new file mode 100644 index 0000000000000..73596f93f5685 --- /dev/null +++ b/src/test/run-make/symlinked-libraries/bar.rs @@ -0,0 +1,15 @@ +// 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. + +extern crate foo; + +fn main() { + foo::bar(); +} diff --git a/src/test/run-make/symlinked-libraries/foo.rs b/src/test/run-make/symlinked-libraries/foo.rs new file mode 100644 index 0000000000000..9fbe36f0376d6 --- /dev/null +++ b/src/test/run-make/symlinked-libraries/foo.rs @@ -0,0 +1,13 @@ +// 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. + +#[crate_type = "dylib"]; + +pub fn bar() {} From 53b9484dafd92f442f8ed092e2648340c6cecf1f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 22 Feb 2014 11:46:06 -0800 Subject: [PATCH 02/18] Use lines_any() when parsing output form "ar" On windows lines are delimited with \r\n while on unix they're delimited with \n. cc #12471 --- src/librustc/back/archive.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/librustc/back/archive.rs b/src/librustc/back/archive.rs index 1df34576c3e6e..e0c570664fe5c 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, From 3ca01676bcbd092b04608cc0eee843b7031e46cb Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Sat, 22 Feb 2014 20:37:52 +0100 Subject: [PATCH 03/18] Remove some obsolete ignored tests * compile-fail/vec-add.rs is obsolete, there are no mutable vectors any more, #2711 is closed * compile-fail/issue-1451.rs is obsolete, there are no more structural records, #1451 is closed * compile-fail/issue-2074.rs is obsolete, an up to date test is in run-pass/nested-enum-same-names.rs, #2074 is closed * compile-fail/omitted-arg-wrong-types.rs is obsolete, #2093 is closed --- src/test/compile-fail/issue-1451.rs | 33 --------- src/test/compile-fail/issue-2074.rs | 23 ------ .../compile-fail/omitted-arg-wrong-types.rs | 21 ------ src/test/compile-fail/vec-add.rs | 73 ------------------- 4 files changed, 150 deletions(-) delete mode 100644 src/test/compile-fail/issue-1451.rs delete mode 100644 src/test/compile-fail/issue-2074.rs delete mode 100644 src/test/compile-fail/omitted-arg-wrong-types.rs delete mode 100644 src/test/compile-fail/vec-add.rs diff --git a/src/test/compile-fail/issue-1451.rs b/src/test/compile-fail/issue-1451.rs deleted file mode 100644 index ce27cc3be38dc..0000000000000 --- a/src/test/compile-fail/issue-1451.rs +++ /dev/null @@ -1,33 +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 - -struct T { f: extern "Rust" fn() }; -struct S { f: extern "Rust" fn() }; - -fn fooS(t: S) { -} - -fn fooT(t: T) { -} - -fn bar() { -} - -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}); -} diff --git a/src/test/compile-fail/issue-2074.rs b/src/test/compile-fail/issue-2074.rs deleted file mode 100644 index 338d0cb439c23..0000000000000 --- a/src/test/compile-fail/issue-2074.rs +++ /dev/null @@ -1,23 +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 - -fn main() { - let one: || -> uint = || { - enum r { a }; - a as uint - }; - let two = || -> uint = || { - enum r { a }; - a as uint - }; - one(); two(); -} diff --git a/src/test/compile-fail/omitted-arg-wrong-types.rs b/src/test/compile-fail/omitted-arg-wrong-types.rs deleted file mode 100644 index 1f1a6849acad5..0000000000000 --- a/src/test/compile-fail/omitted-arg-wrong-types.rs +++ /dev/null @@ -1,21 +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 - #2093 - -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` -} diff --git a/src/test/compile-fail/vec-add.rs b/src/test/compile-fail/vec-add.rs deleted file mode 100644 index 3f1b82d1768d6..0000000000000 --- 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() { -} From 16e635cdfbb6b041886d1bccd28fa5e7e34c9f47 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Sun, 23 Feb 2014 10:56:38 +1100 Subject: [PATCH 04/18] std: make .swap_remove return Option. This is one of the last raw "indexing" method on vectors that returns `T` instead of the Option. --- src/libgreen/stack.rs | 2 +- src/libstd/vec.rs | 50 ++++++++++++++++++++++++++----------------- src/libstd/vec_ng.rs | 10 ++++----- 3 files changed, 35 insertions(+), 27 deletions(-) diff --git a/src/libgreen/stack.rs b/src/libgreen/stack.rs index 8a5e6be17c87d..053d73c010e39 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/libstd/vec.rs b/src/libstd/vec.rs index d8cb8bf3ed19f..cf49ea535623d 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 3532e7b26a405..2f39adc25d341 100644 --- a/src/libstd/vec_ng.rs +++ b/src/libstd/vec_ng.rs @@ -277,15 +277,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] @@ -392,4 +391,3 @@ impl Drop for MoveItems { } } } - From ac64db94bf1d009a43e7f3729434417bd2e59662 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Sun, 23 Feb 2014 10:59:23 +1100 Subject: [PATCH 05/18] std: Add Vec.reserve for rounding-up reservation. `.reserve_exact` can cause pathological O(n^2) behaviour, so providing a `.reserve` that ensures that capacity doubles (if you step 1, 2, ..., n) is more efficient. cc #11949 --- src/libstd/vec_ng.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/libstd/vec_ng.rs b/src/libstd/vec_ng.rs index 2f39adc25d341..52d3405f8c148 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"); @@ -296,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 From 3cc95314c31311138e189d2ad91bb537d034d3c1 Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Sun, 23 Feb 2014 12:07:11 +1100 Subject: [PATCH 06/18] Remove std::default::Default from the prelude --- src/libcollections/hashmap.rs | 1 + src/libstd/prelude.rs | 1 - src/libstd/rand/reseeding.rs | 1 + src/libstd/str.rs | 1 + src/libsyntax/opt_vec.rs | 1 + src/libuuid/lib.rs | 1 + 6 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libcollections/hashmap.rs b/src/libcollections/hashmap.rs index 4f0b7dfb35dde..7ab859796927a 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/libstd/prelude.rs b/src/libstd/prelude.rs index ce746852daed6..63f54da76ba07 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -43,7 +43,6 @@ 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}; diff --git a/src/libstd/rand/reseeding.rs b/src/libstd/rand/reseeding.rs index 758ca22e5c3ec..a916ce173fb60 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 daaf46be18767..12044b4a06a5b 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/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs index 3abd411a00399..325df0ba77775 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/libuuid/lib.rs b/src/libuuid/lib.rs index 7a3ed09a492d7..a978a9074f04d 100644 --- a/src/libuuid/lib.rs +++ b/src/libuuid/lib.rs @@ -66,6 +66,7 @@ extern crate serialize; use std::cast::{transmute,transmute_copy}; use std::char::Char; +use std::default::Default; use std::fmt; use std::hash::{Hash, sip}; use std::num::FromStrRadix; From 84a8893f19c4cf87355984c8d5fa604a5828161a Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Sun, 23 Feb 2014 12:29:42 +1100 Subject: [PATCH 07/18] Remove std::from_str::FromStr from the prelude --- src/libextra/url.rs | 1 + src/libnum/bigint.rs | 2 ++ src/libstd/bool.rs | 1 + src/libstd/io/net/ip.rs | 1 + src/libstd/num/f32.rs | 1 + src/libstd/num/f64.rs | 1 + src/libstd/num/i16.rs | 1 + src/libstd/num/i32.rs | 1 + src/libstd/num/i64.rs | 1 + src/libstd/num/i8.rs | 1 + src/libstd/num/int.rs | 1 + src/libstd/num/u16.rs | 1 + src/libstd/num/u32.rs | 1 + src/libstd/num/u64.rs | 1 + src/libstd/num/u8.rs | 1 + src/libstd/num/uint.rs | 1 + src/libstd/prelude.rs | 1 - src/libsyntax/crateid.rs | 3 +++ src/libtest/lib.rs | 1 + src/libuuid/lib.rs | 1 + src/test/bench/shootout-threadring.rs | 2 ++ 21 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/libextra/url.rs b/src/libextra/url.rs index 0292a18817ccd..5812aaa5038d0 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/libnum/bigint.rs b/src/libnum/bigint.rs index 894b3794581e1..cb3faca017bd4 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,6 +1398,7 @@ 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::{ToPrimitive, FromPrimitive}; diff --git a/src/libstd/bool.rs b/src/libstd/bool.rs index 918d42e1bce46..2376603fcc8f9 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 e4f3676432378..f67ba8fce03e0 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 a98fd31c45727..a686edef99e69 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 5975ce40d84fa..026bd651e0e3f 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 141626ed98a75..0ecb55e510608 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 a43a6e6a288cd..0526f2c488b20 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 e8503d808a703..0c1c01dbf4ab8 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 9f857ff40ff50..881cc46201ef5 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 6d1a50b724fd2..83c9e8ea855bc 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/u16.rs b/src/libstd/num/u16.rs index da0293b341864..d1de1ff0a723c 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 b103e18f7019f..1caec67802539 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 f7956f0128e5e..ab495834eaa5f 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 e6ce9c72e96b2..a0ef574f6cf2f 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 a8c85787f7ec8..95d4a3a50be57 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/prelude.rs b/src/libstd/prelude.rs index 63f54da76ba07..80781ce59f14b 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -43,7 +43,6 @@ 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 from_str::FromStr; pub use iter::{FromIterator, Extendable}; pub use iter::{Iterator, DoubleEndedIterator, RandomAccessIterator, CloneableIterator}; pub use iter::{OrdIterator, MutableDoubleEndedIterator, ExactSize}; diff --git a/src/libsyntax/crateid.rs b/src/libsyntax/crateid.rs index 2417a6fa1bacf..659cd13c94dd1 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/libtest/lib.rs b/src/libtest/lib.rs index 6093948d9f4d4..02950c075829f 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 a978a9074f04d..8dbdedc18483a 100644 --- a/src/libuuid/lib.rs +++ b/src/libuuid/lib.rs @@ -68,6 +68,7 @@ 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 7063194eab862..6ce6fb503a1d8 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"] } From dad52cfcb58cb30170c6247f2053bc0f0d57466a Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Sun, 23 Feb 2014 12:41:43 +1100 Subject: [PATCH 08/18] Remove std::num::ToStrRadix from the prelude --- src/libnum/bigint.rs | 4 ++-- src/libnum/rational.rs | 2 +- src/libstd/num/int_macros.rs | 3 ++- src/libstd/num/uint_macros.rs | 1 + src/libstd/prelude.rs | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/libnum/bigint.rs b/src/libnum/bigint.rs index cb3faca017bd4..63f48ea9d222f 100644 --- a/src/libnum/bigint.rs +++ b/src/libnum/bigint.rs @@ -1400,7 +1400,7 @@ mod biguint_tests { 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; @@ -2058,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 44a916c5d4e22..79ff54cb90c68 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/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs index 030aa2d81fa24..ea62a3ec374d3 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/uint_macros.rs b/src/libstd/num/uint_macros.rs index 001927e603312..719afeb78784a 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 80781ce59f14b..cc1a14a4f822d 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -48,7 +48,7 @@ pub use iter::{Iterator, DoubleEndedIterator, RandomAccessIterator, CloneableIte 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}; From ff79a4471cbf5fa4e78fcf56be129a3d56690127 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Sun, 23 Feb 2014 16:40:04 +1100 Subject: [PATCH 09/18] syntax: record multibyte chars' positions absolutely, not relative to file. Previously multibyte UTF-8 chars were being recorded as byte offsets from the start of the file, and then later compared against global byte positions, resulting in the compiler possibly thinking it had a byte position pointing inside a multibyte character, if there were multibyte characters in any non-crate files. (Although, sometimes the byte offsets line up just right to not ICE, but that was a coincidence.) Fixes #11136. Fixes #11178. --- src/libsyntax/parse/lexer.rs | 3 +- src/test/run-make/unicode-input/Makefile | 6 +++ .../run-make/unicode-input/multiple_files.rs | 54 +++++++++++++++++++ 3 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 src/test/run-make/unicode-input/Makefile create mode 100644 src/test/run-make/unicode-input/multiple_files.rs diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index b711e95bc943b..5bace75a5eace 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/test/run-make/unicode-input/Makefile b/src/test/run-make/unicode-input/Makefile new file mode 100644 index 0000000000000..1e420bddb777b --- /dev/null +++ b/src/test/run-make/unicode-input/Makefile @@ -0,0 +1,6 @@ +-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)" 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 0000000000000..2758ac12bab1b --- /dev/null +++ b/src/test/run-make/unicode-input/multiple_files.rs @@ -0,0 +1,54 @@ +use std::{char, os, run, str}; +use std::rand::{task_rng, Rng}; +use std::io::File; + +// 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 mut w = File::create(&tmpdir.join("unicode_input_multiple_files_chars.rs")).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 = run::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")) + } +} From 8812e8ad4957e3e201dabb62c6c3a8e0b10333a7 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Sun, 23 Feb 2014 17:08:46 +1100 Subject: [PATCH 10/18] syntax: calculate positions of multibyte characters more correctly. They are still are not completely correct, since it does not handle graphemes at all, just codepoints, but at least it handles the common case correctly. The calculation was previously very wrong (rather than just a little bit wrong): it wasn't accounting for the fact that every character is 1 byte, and so multibyte characters were pretending to be zero width. cc #8706 --- src/libsyntax/codemap.rs | 7 ++- src/test/run-make/unicode-input/Makefile | 5 ++ .../run-make/unicode-input/multiple_files.rs | 13 +++- .../run-make/unicode-input/span_length.rs | 62 +++++++++++++++++++ 4 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 src/test/run-make/unicode-input/span_length.rs diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 83700e390cbf1..a67d1b933a857 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/test/run-make/unicode-input/Makefile b/src/test/run-make/unicode-input/Makefile index 1e420bddb777b..2d6ecd3c55efc 100644 --- a/src/test/run-make/unicode-input/Makefile +++ b/src/test/run-make/unicode-input/Makefile @@ -4,3 +4,8 @@ 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 index 2758ac12bab1b..68bec1d215a27 100644 --- a/src/test/run-make/unicode-input/multiple_files.rs +++ b/src/test/run-make/unicode-input/multiple_files.rs @@ -1,3 +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. + use std::{char, os, run, str}; use std::rand::{task_rng, Rng}; use std::io::File; @@ -36,7 +46,8 @@ fn main() { for _ in range(0, 100) { { - let mut w = File::create(&tmpdir.join("unicode_input_multiple_files_chars.rs")).unwrap(); + 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()); } 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 0000000000000..c437b70baf3fc --- /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, run, str}; +use std::rand::{task_rng, Rng}; +use std::io::File; + +// 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 = run::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)); + } +} From 0309104cc59d6290fba2fe6dd9bfdc18aacab5f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Sun, 23 Feb 2014 12:25:11 +0100 Subject: [PATCH 11/18] Mark by-value parameters that are passed on the stack as nocapture The by-value argument is a copy that is only valid for the duration of the function call, therefore keeping any pointer to it that outlives the call is illegal. --- src/librustc/middle/trans/base.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 5b3c18a5a9309..5df6c231b5c23 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); } } } From 6757053cffb585249105fbd76f83a2fe7501219b Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Mon, 24 Feb 2014 00:53:59 +1100 Subject: [PATCH 12/18] syntax: allow stmt/expr macro invocations to be delimited by {}. This makes using control-flow-y macros like `spawn! { ... }` more fluent and natural. cc #11892. --- src/libsyntax/parse/parser.rs | 26 +++++++++++++++-- .../compile-fail/macro-bad-delimiter-ident.rs | 13 +++++++++ .../macro-mismatched-delim-brace-paren.rs | 15 ++++++++++ .../macro-mismatched-delim-paren-brace.rs | 15 ++++++++++ .../macro-with-braces-in-expr-position.rs | 28 +++++++++++++++++++ 5 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 src/test/compile-fail/macro-bad-delimiter-ident.rs create mode 100644 src/test/compile-fail/macro-mismatched-delim-brace-paren.rs create mode 100644 src/test/compile-fail/macro-mismatched-delim-paren-brace.rs create mode 100644 src/test/run-pass/macro-with-braces-in-expr-position.rs diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index dac668da34391..cbe371a06a534 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/test/compile-fail/macro-bad-delimiter-ident.rs b/src/test/compile-fail/macro-bad-delimiter-ident.rs new file mode 100644 index 0000000000000..6f3b8bd421f86 --- /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 0000000000000..d03698c1573b1 --- /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 0000000000000..d80f93d7ad0d0 --- /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/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 0000000000000..2a368568f8ca5 --- /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"); + }; +} From 4690ab0ea84d4381ddca724a51e4a36760149fde Mon Sep 17 00:00:00 2001 From: Edward Wang Date: Mon, 24 Feb 2014 07:02:27 +0800 Subject: [PATCH 13/18] Match binding is assignment In its first pass, namely gather_loans, the borrow checker tracks the initialization sites among other things it does. It does so for let bindings with initializers but not for bindings in match arms, which are effectively also assignments. This patch does that for borrow checker. Closes #12452. --- .../middle/borrowck/gather_loans/mod.rs | 23 +++++---- .../borrowck-match-binding-is-assignment.rs | 51 +++++++++++++++++++ 2 files changed, 64 insertions(+), 10 deletions(-) create mode 100644 src/test/compile-fail/borrowck-match-binding-is-assignment.rs diff --git a/src/librustc/middle/borrowck/gather_loans/mod.rs b/src/librustc/middle/borrowck/gather_loans/mod.rs index 15922d57ba83c..263ed47b29e34 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/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 0000000000000..72d9afd4d2b2b --- /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` + } + } +} From a7b1d65080dc0890d7a870af70870477d8fc1047 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 23 Feb 2014 23:23:08 -0800 Subject: [PATCH 14/18] Run the travis build as one large command It appears that travis doesn't stop running script commands after the first one fails (see https://github.com/travis-ci/travis-ci/issues/1066), so chain all our commands together with && for now. --- .travis.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index a443581b58e9f..2c2ef693d0b3d 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 From 54abbda9b4f9ead316413d2ec5bef926c8bede18 Mon Sep 17 00:00:00 2001 From: George Papanikolaou Date: Mon, 24 Feb 2014 13:41:12 +0200 Subject: [PATCH 15/18] Update source code layout in src/ with the new modules that moved from extra, and with other undocumented folders. also add a note about potential changes. --- src/README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/README.md b/src/README.md index cc67a3717faad..0ac310df1b866 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. From 7fc7c377630717d19d38abeaf76b7c0a5229cc68 Mon Sep 17 00:00:00 2001 From: Jag Talon Date: Mon, 24 Feb 2014 08:36:23 -0500 Subject: [PATCH 16/18] Tutorial: Add std::num::sqrt to the example. We should be using the package std::num::sqrt instead of the sqrt function that was defined to return 0.0 --- src/doc/tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/tutorial.md b/src/doc/tutorial.md index c2469e0c171f8..41bf15c0c149e 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; From 35f2da4063bbf2e6e945fdce547b6855ef061b15 Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Tue, 25 Feb 2014 01:25:53 +0100 Subject: [PATCH 17/18] test: single-variant enum can't be dereferenced Closes #9814 --- src/test/compile-fail/issue-9814.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/test/compile-fail/issue-9814.rs diff --git a/src/test/compile-fail/issue-9814.rs b/src/test/compile-fail/issue-9814.rs new file mode 100644 index 0000000000000..f7609a767a7e0 --- /dev/null +++ b/src/test/compile-fail/issue-9814.rs @@ -0,0 +1,18 @@ +// 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. + +// Verify that single-variant enums cant be de-referenced +// Regression test for issue #9814 + +enum Foo { Bar(int) } + +fn main() { + let _ = *Bar(2); //~ ERROR type `Foo` cannot be dereferenced +} From 7d85546721cf954606a2fe25a63e9fb9e8a256ad Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 24 Feb 2014 21:53:46 -0800 Subject: [PATCH 18/18] Test fixes from rollup --- src/test/run-make/unicode-input/multiple_files.rs | 6 +++--- src/test/run-make/unicode-input/span_length.rs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/run-make/unicode-input/multiple_files.rs b/src/test/run-make/unicode-input/multiple_files.rs index 68bec1d215a27..80371aa984052 100644 --- a/src/test/run-make/unicode-input/multiple_files.rs +++ b/src/test/run-make/unicode-input/multiple_files.rs @@ -8,9 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::{char, os, run, str}; +use std::{char, os, str}; use std::rand::{task_rng, Rng}; -use std::io::File; +use std::io::{File, Process}; // creates unicode_input_multiple_files_{main,chars}.rs, where the // former imports the latter. `_chars` just contains an indentifier @@ -55,7 +55,7 @@ fn main() { // rustc is passed to us with --out-dir and -L etc., so we // can't exec it directly - let result = run::process_output("sh", [~"-c", rustc + " " + main_file_str]).unwrap(); + 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 diff --git a/src/test/run-make/unicode-input/span_length.rs b/src/test/run-make/unicode-input/span_length.rs index c437b70baf3fc..3227f672bcd66 100644 --- a/src/test/run-make/unicode-input/span_length.rs +++ b/src/test/run-make/unicode-input/span_length.rs @@ -8,9 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::{char, os, run, str}; +use std::{char, os, str}; use std::rand::{task_rng, Rng}; -use std::io::File; +use std::io::{File, Process}; // creates a file with `fn main() { }` and checks the // compiler emits a span of the appropriate length (for the @@ -51,7 +51,7 @@ fn main() { // rustc is passed to us with --out-dir and -L etc., so we // can't exec it directly - let result = run::process_output("sh", [~"-c", rustc + " " + main_file_str]).unwrap(); + let result = Process::output("sh", [~"-c", rustc + " " + main_file_str]).unwrap(); let err = str::from_utf8_lossy(result.error);