From 80f92f5c5fedadd131842977c0b9b21806f3902f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 9 Mar 2014 23:20:05 -0700 Subject: [PATCH 01/12] std: Relax an assertion in oneshot selection The assertion was erroneously ensuring that there was no data on the port when the port had selection aborted on it. This assertion was written in error because it's possible for data to be waiting on a port, even after it was disconnected. When aborting selection, if we see that there's data on the port, then we return true that data is available on the port. Closes #12802 --- src/libstd/comm/oneshot.rs | 19 +++++++++----- src/libstd/comm/select.rs | 52 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 7 deletions(-) diff --git a/src/libstd/comm/oneshot.rs b/src/libstd/comm/oneshot.rs index 9deccfeb87566..0f78c1971bceb 100644 --- a/src/libstd/comm/oneshot.rs +++ b/src/libstd/comm/oneshot.rs @@ -339,14 +339,19 @@ impl Packet { DATA => Ok(true), // If the other end has hung up, then we have complete ownership - // of the port. We need to check to see if there was an upgrade - // requested, and if so, the other end needs to have its selection - // aborted. + // of the port. First, check if there was data waiting for us. This + // is possible if the other end sent something and then hung up. + // + // We then need to check to see if there was an upgrade requested, + // and if so, the upgraded port needs to have its selection aborted. DISCONNECTED => { - assert!(self.data.is_none()); - match mem::replace(&mut self.upgrade, SendUsed) { - GoUp(port) => Err(port), - _ => Ok(true), + if self.data.is_some() { + Ok(true) + } else { + match mem::replace(&mut self.upgrade, SendUsed) { + GoUp(port) => Err(port), + _ => Ok(true), + } } } diff --git a/src/libstd/comm/select.rs b/src/libstd/comm/select.rs index 75e7265705a77..3c6828fc14fa0 100644 --- a/src/libstd/comm/select.rs +++ b/src/libstd/comm/select.rs @@ -597,4 +597,56 @@ mod test { unsafe { h.add(); } assert_eq!(s.wait2(false), h.id); }) + + test!(fn oneshot_data_waiting() { + let (p, c) = Chan::new(); + let (p2, c2) = Chan::new(); + spawn(proc() { + select! { + () = p.recv() => {} + } + c2.send(()); + }); + + for _ in range(0, 100) { task::deschedule() } + c.send(()); + p2.recv(); + }) + + test!(fn stream_data_waiting() { + let (p, c) = Chan::new(); + let (p2, c2) = Chan::new(); + c.send(()); + c.send(()); + p.recv(); + p.recv(); + spawn(proc() { + select! { + () = p.recv() => {} + } + c2.send(()); + }); + + for _ in range(0, 100) { task::deschedule() } + c.send(()); + p2.recv(); + }) + + test!(fn shared_data_waiting() { + let (p, c) = Chan::new(); + let (p2, c2) = Chan::new(); + drop(c.clone()); + c.send(()); + p.recv(); + spawn(proc() { + select! { + () = p.recv() => {} + } + c2.send(()); + }); + + for _ in range(0, 100) { task::deschedule() } + c.send(()); + p2.recv(); + }) } From 91bed14ca8085887a26d029d785d853ad2587718 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 10 Mar 2014 15:10:56 -0700 Subject: [PATCH 02/12] green: Fix a scheduler assertion on yielding This commit fixes a small bug in the green scheduler where a scheduler task calling `maybe_yield` would trip the assertion that `self.yield_check_count > 0` This behavior was seen when a scheduler task was scheduled many times successively, sending messages in a loop (via the channel `send` method), which in turn invokes `maybe_yield`. Yielding on a sched task doesn't make sense because as soon as it's done it will implicitly do a yield, and for this reason the yield check is just skipped if it's a sched task. I am unable to create a reliable test for this behavior, as there's no direct way to have control over the scheduler tasks. cc #12666, I discovered this when investigating that issue --- src/libgreen/sched.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/libgreen/sched.rs b/src/libgreen/sched.rs index aae0034263e37..872d6de175820 100644 --- a/src/libgreen/sched.rs +++ b/src/libgreen/sched.rs @@ -832,6 +832,20 @@ impl Scheduler { } pub fn maybe_yield(mut ~self, cur: ~GreenTask) { + // It's possible for sched tasks to possibly call this function, and it + // just means that they're likely sending on channels (which + // occasionally call this function). Sched tasks follow different paths + // when executing yield_now(), which may possibly trip the assertion + // below. For this reason, we just have sched tasks bail out soon. + // + // Sched tasks have no need to yield anyway because as soon as they + // return they'll yield to other threads by falling back to the event + // loop. Additionally, we completely control sched tasks, so we can make + // sure that they never execute more than enough code. + if cur.is_sched() { + return cur.put_with_sched(self) + } + // The number of times to do the yield check before yielding, chosen // arbitrarily. rtassert!(self.yield_check_count > 0); From 207ebf13f12d8fa4449d66cd86407de03f264667 Mon Sep 17 00:00:00 2001 From: Peter Marheine Date: Mon, 10 Mar 2014 19:30:23 -0400 Subject: [PATCH 03/12] doc: discuss try! in std::io --- src/libstd/io/mod.rs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 7a18f24140a16..1c10c7b61c364 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -172,6 +172,40 @@ need to inspect or unwrap the `IoResult` and we simply call `write_line` on it. If `new` returned an `Err(..)` then the followup call to `write_line` will also return an error. +## `try!` + +Explicit pattern matching on `IoResult`s can get quite verbose, especially +when performing many I/O operations. Some examples (like those above) are +alleviated with extra methods implemented on `IoResult`, but others have more +complex interdependencies among each I/O operation. + +The `try!` macro from `std::macros` is provided as a method of early-return +inside `Result`-returning functions. It expands to an early-return on `Err` +and otherwise unwraps the contained `Ok` value. + +If you wanted to read several `u32`s from a file and return their product: + +```rust +use std::io::{File, IoResult}; + +fn file_product(p: &Path) -> IoResult { + let mut f = File::open(p); + let x1 = try!(f.read_le_u32()); + let x2 = try!(f.read_le_u32()); + + Ok(x1 * x2) +} + +match file_product(&Path::new("numbers.bin")) { + Ok(x) => println!("{}", x), + Err(e) => println!("Failed to read numbers!") +} +``` + +With `try!` in `file_product`, each `read_le_u32` need not be directly +concerned with error handling; instead its caller is responsible for +responding to errors that may occur while attempting to read the numbers. + */ #[deny(unused_must_use)]; From 9959188d0e653871b4995a25ce066dbf0726f132 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Tue, 25 Feb 2014 08:03:41 -0800 Subject: [PATCH 04/12] Use generic impls for `Hash` --- src/libcollections/lru_cache.rs | 8 ++++---- src/libextra/lib.rs | 2 +- src/libextra/url.rs | 14 +++++++------- src/libstd/path/posix.rs | 8 ++++---- src/libstd/path/windows.rs | 8 ++++---- src/libstd/str.rs | 11 +++++++---- src/libuuid/lib.rs | 15 +++++++++++---- 7 files changed, 38 insertions(+), 28 deletions(-) diff --git a/src/libcollections/lru_cache.rs b/src/libcollections/lru_cache.rs index 0aace71813eba..28ea36fa2317a 100644 --- a/src/libcollections/lru_cache.rs +++ b/src/libcollections/lru_cache.rs @@ -39,7 +39,7 @@ use std::cast; use std::container::Container; -use std::hash::{Hash, sip}; +use std::hash::Hash; use std::fmt; use std::ptr; @@ -62,9 +62,9 @@ pub struct LruCache { priv tail: *mut LruEntry, } -impl Hash for KeyRef { - fn hash(&self, s: &mut sip::SipState) { - unsafe {(*self.k).hash(s)} +impl> Hash for KeyRef { + fn hash(&self, state: &mut S) { + unsafe { (*self.k).hash(state) } } } diff --git a/src/libextra/lib.rs b/src/libextra/lib.rs index 673eb7e76de49..32de7bf08667f 100644 --- a/src/libextra/lib.rs +++ b/src/libextra/lib.rs @@ -29,7 +29,7 @@ Rust extras are part of the standard Rust distribution. html_favicon_url = "http://www.rust-lang.org/favicon.ico", html_root_url = "http://static.rust-lang.org/doc/master")]; -#[feature(macro_rules, globs, managed_boxes, asm)]; +#[feature(macro_rules, globs, managed_boxes, asm, default_type_params)]; #[deny(non_camel_case_types)]; #[deny(missing_doc)]; diff --git a/src/libextra/url.rs b/src/libextra/url.rs index 5812aaa5038d0..6be90c0056d11 100644 --- a/src/libextra/url.rs +++ b/src/libextra/url.rs @@ -14,7 +14,7 @@ use std::cmp::Eq; use std::fmt; -use std::hash::{Hash, sip}; +use std::hash::Hash; use std::io::BufReader; use std::from_str::FromStr; use std::uint; @@ -849,15 +849,15 @@ impl fmt::Show for Path { } } -impl Hash for Url { - fn hash(&self, s: &mut sip::SipState) { - self.to_str().hash(s) +impl Hash for Url { + fn hash(&self, state: &mut S) { + self.to_str().hash(state) } } -impl Hash for Path { - fn hash(&self, s: &mut sip::SipState) { - self.to_str().hash(s) +impl Hash for Path { + fn hash(&self, state: &mut S) { + self.to_str().hash(state) } } diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs index a3380b5db1d2b..f7588f6ca599c 100644 --- a/src/libstd/path/posix.rs +++ b/src/libstd/path/posix.rs @@ -15,7 +15,7 @@ use c_str::{CString, ToCStr}; use clone::Clone; use cmp::Eq; use from_str::FromStr; -use hash::{Hash, sip}; +use io::Writer; use iter::{AdditiveIterator, Extendable, Iterator, Map}; use option::{Option, None, Some}; use str; @@ -88,10 +88,10 @@ impl ToCStr for Path { } } -impl Hash for Path { +impl ::hash::Hash for Path { #[inline] - fn hash(&self, s: &mut sip::SipState) { - self.repr.hash(s) + fn hash(&self, hasher: &mut H) { + self.repr.hash(hasher) } } diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index 5b358819e4168..6d05001beab92 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -17,7 +17,7 @@ use clone::Clone; use container::Container; use cmp::Eq; use from_str::FromStr; -use hash::{Hash, sip}; +use io::Writer; use iter::{AdditiveIterator, DoubleEndedIterator, Extendable, Rev, Iterator, Map}; use option::{Option, Some, None}; use str; @@ -112,10 +112,10 @@ impl ToCStr for Path { } } -impl Hash for Path { +impl ::hash::Hash for Path { #[inline] - fn hash(&self, s: &mut sip::SipState) { - self.repr.hash(s) + fn hash(&self, hasher: &mut H) { + self.repr.hash(hasher) } } diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 5bd14e717b1b9..1900d0ffedd4f 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -89,7 +89,7 @@ use clone::Clone; use cmp::{Eq, TotalEq, Ord, TotalOrd, Equiv, Ordering}; use container::{Container, Mutable}; use fmt; -use hash::{Hash, sip}; +use io::Writer; use iter::{Iterator, FromIterator, Extendable, range}; use iter::{Filter, AdditiveIterator, Map}; use iter::{Rev, DoubleEndedIterator, ExactSize}; @@ -1331,10 +1331,13 @@ impl<'a> Default for MaybeOwned<'a> { fn default() -> MaybeOwned<'a> { Slice("") } } -impl<'a> Hash for MaybeOwned<'a> { +impl<'a, H: Writer> ::hash::Hash for MaybeOwned<'a> { #[inline] - fn hash(&self, s: &mut sip::SipState) { - self.as_slice().hash(s) + fn hash(&self, hasher: &mut H) { + match *self { + Slice(s) => s.hash(hasher), + Owned(ref s) => s.hash(hasher), + } } } diff --git a/src/libuuid/lib.rs b/src/libuuid/lib.rs index aa17cd4680948..922393d8bb3af 100644 --- a/src/libuuid/lib.rs +++ b/src/libuuid/lib.rs @@ -59,6 +59,12 @@ Examples of string representations: #[crate_type = "dylib"]; #[license = "MIT/ASL2"]; +#[feature(default_type_params)]; + +// NOTE remove the following two attributes after the next snapshot. +#[allow(unrecognized_lint)]; +#[allow(default_type_param_usage)]; + // test harness access #[cfg(test)] extern crate test; @@ -71,7 +77,7 @@ use std::char::Char; use std::default::Default; use std::fmt; use std::from_str::FromStr; -use std::hash::{Hash, sip}; +use std::hash::Hash; use std::num::FromStrRadix; use std::str; use std::vec; @@ -116,9 +122,10 @@ pub struct Uuid { /// The 128-bit number stored in 16 bytes bytes: UuidBytes } -impl Hash for Uuid { - fn hash(&self, s: &mut sip::SipState) { - self.bytes.slice_from(0).hash(s) + +impl Hash for Uuid { + fn hash(&self, state: &mut S) { + self.bytes.hash(state) } } From aac6e317639140a149d97116d43e66b5bd76bce3 Mon Sep 17 00:00:00 2001 From: lpy Date: Tue, 11 Mar 2014 21:39:26 +0800 Subject: [PATCH 05/12] Remove remaining nolink usages.(fixes #12810) --- src/doc/rust.md | 1 - src/libnative/io/file_win32.rs | 1 - src/librustc/middle/lint.rs | 2 +- src/libstd/io/test.rs | 1 - src/libstd/libc.rs | 23 ------------------- src/libstd/os.rs | 4 ---- .../compile-fail/attrs-after-extern-mod.rs | 1 - src/test/compile-fail/lint-ctypes.rs | 1 - .../compile-fail/nolink-with-link-args.rs | 1 - src/test/run-pass/c-stack-returning-int64.rs | 1 - src/test/run-pass/foreign-fn-linkname.rs | 1 - src/test/run-pass/foreign-mod-unused-const.rs | 1 - src/test/run-pass/foreign-struct.rs | 1 - src/test/run-pass/foreign2.rs | 4 ---- src/test/run-pass/nil-decl-in-foreign.rs | 1 - src/test/run-pass/warn-ctypes-inhibit.rs | 1 - 16 files changed, 1 insertion(+), 44 deletions(-) diff --git a/src/doc/rust.md b/src/doc/rust.md index d1cef9a061477..9e2b934d0abc4 100644 --- a/src/doc/rust.md +++ b/src/doc/rust.md @@ -1472,7 +1472,6 @@ and are instead terminated by a semicolon. ~~~~ # use std::libc::{c_char, FILE}; -# #[nolink] extern { fn fopen(filename: *c_char, mode: *c_char) -> *FILE; diff --git a/src/libnative/io/file_win32.rs b/src/libnative/io/file_win32.rs index e880bd05cf7fc..8f4f9259ab7ac 100644 --- a/src/libnative/io/file_win32.rs +++ b/src/libnative/io/file_win32.rs @@ -335,7 +335,6 @@ pub fn readdir(p: &CString) -> IoResult<~[Path]> { }).map(|path| root.join(path)).collect() } - #[nolink] extern { fn rust_list_dir_wfd_size() -> libc::size_t; fn rust_list_dir_wfd_fp_buf(wfd: *libc::c_void) -> *u16; diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 1351e87c7f648..3e3a94f7f0f66 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -979,7 +979,7 @@ static other_attrs: &'static [&'static str] = &[ "macro_export", "must_use", //mod-level - "path", "link_name", "link_args", "nolink", "macro_escape", "no_implicit_prelude", + "path", "link_name", "link_args", "macro_escape", "no_implicit_prelude", // fn-level "test", "bench", "should_fail", "ignore", "inline", "lang", "main", "start", diff --git a/src/libstd/io/test.rs b/src/libstd/io/test.rs index d6f7f58f01c84..73d52654ebf33 100644 --- a/src/libstd/io/test.rs +++ b/src/libstd/io/test.rs @@ -150,7 +150,6 @@ mod darwin_fd_limit { rlim_cur: rlim_t, rlim_max: rlim_t } - #[nolink] extern { // name probably doesn't need to be mut, but the C function doesn't specify const fn sysctl(name: *mut libc::c_int, namelen: libc::c_uint, diff --git a/src/libstd/libc.rs b/src/libstd/libc.rs index afd524e9d7afe..c602c2fc27f8e 100644 --- a/src/libstd/libc.rs +++ b/src/libstd/libc.rs @@ -3306,7 +3306,6 @@ pub mod funcs { // or anything. The same is not true of POSIX. pub mod c95 { - #[nolink] pub mod ctype { use libc::types::os::arch::c95::{c_char, c_int}; @@ -3327,7 +3326,6 @@ pub mod funcs { } } - #[nolink] pub mod stdio { use libc::types::common::c95::{FILE, c_void, fpos_t}; use libc::types::os::arch::c95::{c_char, c_int, c_long, size_t}; @@ -3383,7 +3381,6 @@ pub mod funcs { } } - #[nolink] pub mod stdlib { use libc::types::common::c95::c_void; use libc::types::os::arch::c95::{c_char, c_double, c_int}; @@ -3416,7 +3413,6 @@ pub mod funcs { } } - #[nolink] pub mod string { use libc::types::common::c95::c_void; use libc::types::os::arch::c95::{c_char, c_int, size_t}; @@ -3461,7 +3457,6 @@ pub mod funcs { #[cfg(target_os = "win32")] pub mod posix88 { - #[nolink] pub mod stat_ { use libc::types::os::common::posix01::{stat, utimbuf}; use libc::types::os::arch::c95::{c_int, c_char, wchar_t}; @@ -3486,7 +3481,6 @@ pub mod funcs { } } - #[nolink] pub mod stdio { use libc::types::common::c95::FILE; use libc::types::os::arch::c95::{c_int, c_char}; @@ -3503,7 +3497,6 @@ pub mod funcs { } } - #[nolink] pub mod fcntl { use libc::types::os::arch::c95::{c_int, c_char, wchar_t}; extern { @@ -3518,12 +3511,10 @@ pub mod funcs { } } - #[nolink] pub mod dirent { // Not supplied at all. } - #[nolink] pub mod unistd { use libc::types::common::c95::c_void; use libc::types::os::arch::c95::{c_int, c_uint, c_char, @@ -3590,7 +3581,6 @@ pub mod funcs { use libc::types::os::arch::posix01::stat; use libc::types::os::arch::posix88::mode_t; - #[nolink] extern { pub fn chmod(path: *c_char, mode: mode_t) -> c_int; pub fn fchmod(fd: c_int, mode: mode_t) -> c_int; @@ -3618,7 +3608,6 @@ pub mod funcs { } } - #[nolink] pub mod stdio { use libc::types::common::c95::FILE; use libc::types::os::arch::c95::{c_char, c_int}; @@ -3631,7 +3620,6 @@ pub mod funcs { } } - #[nolink] pub mod fcntl { use libc::types::os::arch::c95::{c_char, c_int}; use libc::types::os::arch::posix88::mode_t; @@ -3644,7 +3632,6 @@ pub mod funcs { } } - #[nolink] pub mod dirent { use libc::types::common::posix88::{DIR, dirent_t}; use libc::types::os::arch::c95::{c_char, c_int, c_long}; @@ -3678,7 +3665,6 @@ pub mod funcs { } } - #[nolink] pub mod unistd { use libc::types::common::c95::c_void; use libc::types::os::arch::c95::{c_char, c_int, c_long, c_uint}; @@ -3748,7 +3734,6 @@ pub mod funcs { } } - #[nolink] pub mod signal { use libc::types::os::arch::c95::{c_int}; use libc::types::os::arch::posix88::{pid_t}; @@ -3758,7 +3743,6 @@ pub mod funcs { } } - #[nolink] pub mod mman { use libc::types::common::c95::{c_void}; use libc::types::os::arch::c95::{size_t, c_int, c_char}; @@ -3796,7 +3780,6 @@ pub mod funcs { #[cfg(target_os = "macos")] #[cfg(target_os = "freebsd")] pub mod posix01 { - #[nolink] pub mod stat_ { use libc::types::os::arch::c95::{c_char, c_int}; use libc::types::os::arch::posix01::stat; @@ -3813,7 +3796,6 @@ pub mod funcs { } } - #[nolink] pub mod unistd { use libc::types::os::arch::c95::{c_char, c_int, size_t}; use libc::types::os::arch::posix88::{ssize_t, off_t}; @@ -3841,7 +3823,6 @@ pub mod funcs { } } - #[nolink] pub mod wait { use libc::types::os::arch::c95::{c_int}; use libc::types::os::arch::posix88::{pid_t}; @@ -3852,7 +3833,6 @@ pub mod funcs { } } - #[nolink] pub mod glob { use libc::types::os::arch::c95::{c_char, c_int}; use libc::types::os::common::posix01::{glob_t}; @@ -3867,7 +3847,6 @@ pub mod funcs { } } - #[nolink] pub mod mman { use libc::types::common::c95::{c_void}; use libc::types::os::arch::c95::{c_int, size_t}; @@ -4032,7 +4011,6 @@ pub mod funcs { } #[cfg(target_os = "macos")] - #[nolink] pub mod extra { use libc::types::os::arch::c95::{c_char, c_int}; @@ -4256,7 +4234,6 @@ pub mod funcs { use libc::types::os::arch::c95::{c_int, c_long}; use libc::types::os::arch::c99::intptr_t; - #[nolink] extern { #[link_name = "_commit"] pub fn commit(fd: c_int) -> c_int; diff --git a/src/libstd/os.rs b/src/libstd/os.rs index e529daaa500d6..3a86aa3d6b689 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -615,7 +615,6 @@ pub fn errno() -> int { #[cfg(target_os = "macos")] #[cfg(target_os = "freebsd")] fn errno_location() -> *c_int { - #[nolink] extern { fn __error() -> *c_int; } @@ -627,7 +626,6 @@ pub fn errno() -> int { #[cfg(target_os = "linux")] #[cfg(target_os = "android")] fn errno_location() -> *c_int { - #[nolink] extern { fn __errno_location() -> *c_int; } @@ -665,7 +663,6 @@ pub fn last_os_error() -> ~str { #[cfg(target_os = "freebsd")] fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: libc::size_t) -> c_int { - #[nolink] extern { fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: libc::size_t) -> c_int; @@ -681,7 +678,6 @@ pub fn last_os_error() -> ~str { #[cfg(target_os = "linux")] fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: libc::size_t) -> c_int { - #[nolink] extern { fn __xpg_strerror_r(errnum: c_int, buf: *mut c_char, diff --git a/src/test/compile-fail/attrs-after-extern-mod.rs b/src/test/compile-fail/attrs-after-extern-mod.rs index 3102fb2664f7d..44b6ecdee7073 100644 --- a/src/test/compile-fail/attrs-after-extern-mod.rs +++ b/src/test/compile-fail/attrs-after-extern-mod.rs @@ -14,7 +14,6 @@ use std::libc; -#[nolink] extern { static mut rust_dbg_static_mut: libc::c_int; pub fn rust_dbg_static_mut_check_four(); diff --git a/src/test/compile-fail/lint-ctypes.rs b/src/test/compile-fail/lint-ctypes.rs index a0c027b2d6b3f..0a1b78c8d5d0a 100644 --- a/src/test/compile-fail/lint-ctypes.rs +++ b/src/test/compile-fail/lint-ctypes.rs @@ -12,7 +12,6 @@ use std::libc; -#[nolink] extern { pub fn bare_type1(size: int); //~ ERROR: found rust type pub fn bare_type2(size: uint); //~ ERROR: found rust type diff --git a/src/test/compile-fail/nolink-with-link-args.rs b/src/test/compile-fail/nolink-with-link-args.rs index a1603ee945316..de929b8bfc923 100644 --- a/src/test/compile-fail/nolink-with-link-args.rs +++ b/src/test/compile-fail/nolink-with-link-args.rs @@ -17,7 +17,6 @@ the compiler output. */ #[feature(link_args)]; #[link_args = "aFdEfSeVEEE"] -#[nolink] extern {} fn main() { } diff --git a/src/test/run-pass/c-stack-returning-int64.rs b/src/test/run-pass/c-stack-returning-int64.rs index 940f62789bbc3..9a02768faebe1 100644 --- a/src/test/run-pass/c-stack-returning-int64.rs +++ b/src/test/run-pass/c-stack-returning-int64.rs @@ -11,7 +11,6 @@ mod libc { use std::libc::{c_char, c_long, c_longlong}; - #[nolink] extern { pub fn atol(x: *c_char) -> c_long; pub fn atoll(x: *c_char) -> c_longlong; diff --git a/src/test/run-pass/foreign-fn-linkname.rs b/src/test/run-pass/foreign-fn-linkname.rs index b9d8d622731d3..7e480f1c32b50 100644 --- a/src/test/run-pass/foreign-fn-linkname.rs +++ b/src/test/run-pass/foreign-fn-linkname.rs @@ -13,7 +13,6 @@ extern crate extra; mod libc { use std::libc::{c_char, size_t}; - #[nolink] extern { #[link_name = "strlen"] pub fn my_strlen(str: *c_char) -> size_t; diff --git a/src/test/run-pass/foreign-mod-unused-const.rs b/src/test/run-pass/foreign-mod-unused-const.rs index 977488d4529af..2f58765394131 100644 --- a/src/test/run-pass/foreign-mod-unused-const.rs +++ b/src/test/run-pass/foreign-mod-unused-const.rs @@ -11,7 +11,6 @@ mod foo { use std::libc::c_int; - #[nolink] extern { pub static errno: c_int; } diff --git a/src/test/run-pass/foreign-struct.rs b/src/test/run-pass/foreign-struct.rs index a70fec9265942..e242071fb26bc 100644 --- a/src/test/run-pass/foreign-struct.rs +++ b/src/test/run-pass/foreign-struct.rs @@ -15,7 +15,6 @@ pub enum void { } mod bindgen { use super::void; - #[nolink] extern { pub fn printf(v: void); } diff --git a/src/test/run-pass/foreign2.rs b/src/test/run-pass/foreign2.rs index 350a3d6f4fc29..7c9d2dfa87cd1 100644 --- a/src/test/run-pass/foreign2.rs +++ b/src/test/run-pass/foreign2.rs @@ -9,26 +9,22 @@ // except according to those terms. mod bar { - #[nolink] extern {} } mod zed { - #[nolink] extern {} } mod libc { use std::libc::{c_int, c_void, size_t, ssize_t}; - #[nolink] extern { pub fn write(fd: c_int, buf: *c_void, count: size_t) -> ssize_t; } } mod baz { - #[nolink] extern {} } diff --git a/src/test/run-pass/nil-decl-in-foreign.rs b/src/test/run-pass/nil-decl-in-foreign.rs index 15795f954b8e7..e23c970e29a58 100644 --- a/src/test/run-pass/nil-decl-in-foreign.rs +++ b/src/test/run-pass/nil-decl-in-foreign.rs @@ -10,7 +10,6 @@ // Issue #901 mod libc { - #[nolink] extern { pub fn printf(x: ()); } diff --git a/src/test/run-pass/warn-ctypes-inhibit.rs b/src/test/run-pass/warn-ctypes-inhibit.rs index f2cc2d79a946e..30ce77153116f 100644 --- a/src/test/run-pass/warn-ctypes-inhibit.rs +++ b/src/test/run-pass/warn-ctypes-inhibit.rs @@ -13,7 +13,6 @@ #[allow(ctypes)]; mod libc { - #[nolink] extern { pub fn malloc(size: int) -> *u8; } From d28d5b7fb4ee11d29260b477b70ac32c25f61cff Mon Sep 17 00:00:00 2001 From: Micah Chalmer Date: Tue, 11 Mar 2014 20:23:32 -0400 Subject: [PATCH 06/12] Emacs: always jump the cursor if needed on indent The rust-mode-indent-line function had a check, which ran after all the calculations for how to indent had already happened, that skipped actually performing the indent if the line was already at the right indentation. Because of that, the cursor did not jump to the indentation if the line wasn't changing. This was particularly annoying if there was nothing but spaces on the line and you were at the beginning of it--it looked like the indent just wasn't working. This removes the check and adds test cases to cover this. --- src/etc/emacs/rust-mode-tests.el | 43 +++++++++++++++++++++++++++++++- src/etc/emacs/rust-mode.el | 16 ++++++------ 2 files changed, 50 insertions(+), 9 deletions(-) diff --git a/src/etc/emacs/rust-mode-tests.el b/src/etc/emacs/rust-mode-tests.el index 63c1a077c8c3d..a4e837958c91b 100644 --- a/src/etc/emacs/rust-mode-tests.el +++ b/src/etc/emacs/rust-mode-tests.el @@ -570,6 +570,11 @@ fn indenting_middle_of_line() { pull_me_back_in(); } } + +fn indented_already() { + + // The previous line already has its spaces +} " ;; Symbol -> (line column) @@ -596,7 +601,15 @@ fn indenting_middle_of_line() { (after-whitespace-indent-start (13 1)) (after-whitespace-indent-target (13 8)) (middle-pull-indent-start (15 19)) - (middle-pull-indent-target (15 12)))) + (middle-pull-indent-target (15 12)) + (blank-line-indented-already-bol-start (20 0)) + (blank-line-indented-already-bol-target (20 4)) + (blank-line-indented-already-middle-start (20 2)) + (blank-line-indented-already-middle-target (20 4)) + (nonblank-line-indented-already-bol-start (21 0)) + (nonblank-line-indented-already-bol-target (21 4)) + (nonblank-line-indented-already-middle-start (21 2)) + (nonblank-line-indented-already-middle-target (21 4)))) (defun rust-get-buffer-pos (pos-symbol) "Get buffer position from POS-SYMBOL. @@ -793,3 +806,31 @@ All positions are position symbols found in `rust-test-positions-alist'." 'middle-pull-indent-start 'middle-pull-indent-target #'indent-for-tab-command)) + +(ert-deftest indent-line-blank-line-indented-already-bol () + (rust-test-motion + rust-test-indent-motion-string + 'blank-line-indented-already-bol-start + 'blank-line-indented-already-bol-target + #'indent-for-tab-command)) + +(ert-deftest indent-line-blank-line-indented-already-middle () + (rust-test-motion + rust-test-indent-motion-string + 'blank-line-indented-already-middle-start + 'blank-line-indented-already-middle-target + #'indent-for-tab-command)) + +(ert-deftest indent-line-nonblank-line-indented-already-bol () + (rust-test-motion + rust-test-indent-motion-string + 'nonblank-line-indented-already-bol-start + 'nonblank-line-indented-already-bol-target + #'indent-for-tab-command)) + +(ert-deftest indent-line-nonblank-line-indented-already-middle () + (rust-test-motion + rust-test-indent-motion-string + 'nonblank-line-indented-already-middle-start + 'nonblank-line-indented-already-middle-target + #'indent-for-tab-command)) diff --git a/src/etc/emacs/rust-mode.el b/src/etc/emacs/rust-mode.el index b304df8f14c16..3a99af3446c2e 100644 --- a/src/etc/emacs/rust-mode.el +++ b/src/etc/emacs/rust-mode.el @@ -140,14 +140,14 @@ ;; Otherwise, we are continuing the same expression from the previous line, ;; so add one additional indent level (+ baseline rust-indent-offset)))))))))) - (when (not (eq (current-indentation) indent)) - ;; If we're at the beginning of the line (before or at the current - ;; indentation), jump with the indentation change. Otherwise, save the - ;; excursion so that adding the indentations will leave us at the - ;; equivalent position within the line to where we were before. - (if (<= (current-column) (current-indentation)) - (indent-line-to indent) - (save-excursion (indent-line-to indent)))))) + + ;; If we're at the beginning of the line (before or at the current + ;; indentation), jump with the indentation change. Otherwise, save the + ;; excursion so that adding the indentations will leave us at the + ;; equivalent position within the line to where we were before. + (if (<= (current-column) (current-indentation)) + (indent-line-to indent) + (save-excursion (indent-line-to indent))))) ;; Font-locking definitions and helpers From 0bfb61ed9d3c32989cea49c11e838229ddfb855e Mon Sep 17 00:00:00 2001 From: zslayton Date: Tue, 11 Mar 2014 23:04:36 -0400 Subject: [PATCH 07/12] Closes #12829. Names changed for consistency, find_path optimized, method impls refactored to reduce repitition. Fixed formatting, reworked find_path to use fewer Options. Removed stray tab. --- src/libserialize/json.rs | 59 ++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 35 deletions(-) diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index c5d10d25838ce..6ce555ba9f74a 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -720,10 +720,17 @@ impl Json { } /// Attempts to get a nested Json Object for each key in `keys`. - /// If any key is found not to exist, get_path will return None. + /// If any key is found not to exist, find_path will return None. /// Otherwise, it will return the Json value associated with the final key. pub fn find_path<'a>(&'a self, keys: &[&~str]) -> Option<&'a Json>{ - keys.iter().fold(Some(self), |target, key| target.map_or(None, |t| t.find(*key))) + let mut target = self; + for key in keys.iter() { + match target.find(*key) { + Some(t) => { target = t; }, + None => return None + } + } + Some(target) } /// If the Json value is an Object, performs a depth-first search until @@ -752,10 +759,7 @@ impl Json { /// Returns true if the Json value is an Object. Returns false otherwise. pub fn is_object<'a>(&'a self) -> bool { - match self { - &Object(_) => true, - _ => false - } + self.as_object().is_some() } /// If the Json value is an Object, returns the associated TreeMap. @@ -769,10 +773,7 @@ impl Json { /// Returns true if the Json value is a List. Returns false otherwise. pub fn is_list<'a>(&'a self) -> bool { - match self { - &List(_) => true, - _ => false - } + self.as_list().is_some() } /// If the Json value is a List, returns the associated vector. @@ -785,16 +786,13 @@ impl Json { } /// Returns true if the Json value is a String. Returns false otherwise. - pub fn is_str<'a>(&'a self) -> bool { - match self { - &String(_) => true, - _ => false - } + pub fn is_string<'a>(&'a self) -> bool { + self.as_string().is_some() } /// If the Json value is a String, returns the associated str. /// Returns None otherwise. - pub fn as_str<'a>(&'a self) -> Option<&'a str> { + pub fn as_string<'a>(&'a self) -> Option<&'a str> { match *self { String(ref s) => Some(s.as_slice()), _ => None @@ -803,10 +801,7 @@ impl Json { /// Returns true if the Json value is a Number. Returns false otherwise. pub fn is_number(&self) -> bool { - match self { - &Number(_) => true, - _ => false - } + self.as_number().is_some() } /// If the Json value is a Number, returns the associated f64. @@ -820,10 +815,7 @@ impl Json { /// Returns true if the Json value is a Boolean. Returns false otherwise. pub fn is_boolean(&self) -> bool { - match self { - &Boolean(_) => true, - _ => false - } + self.as_boolean().is_some() } /// If the Json value is a Boolean, returns the associated bool. @@ -837,10 +829,7 @@ impl Json { /// Returns true if the Json value is a Null. Returns false otherwise. pub fn is_null(&self) -> bool { - match self { - &Null => true, - _ => false - } + self.as_null().is_some() } /// If the Json value is a Null, returns (). @@ -2430,20 +2419,20 @@ mod tests { fn test_find(){ let json_value = from_str("{\"dog\" : \"cat\"}").unwrap(); let found_str = json_value.find(&~"dog"); - assert!(found_str.is_some() && found_str.unwrap().as_str().unwrap() == &"cat"); + assert!(found_str.is_some() && found_str.unwrap().as_string().unwrap() == &"cat"); } #[test] fn test_find_path(){ let json_value = from_str("{\"dog\":{\"cat\": {\"mouse\" : \"cheese\"}}}").unwrap(); let found_str = json_value.find_path(&[&~"dog", &~"cat", &~"mouse"]); - assert!(found_str.is_some() && found_str.unwrap().as_str().unwrap() == &"cheese"); + assert!(found_str.is_some() && found_str.unwrap().as_string().unwrap() == &"cheese"); } #[test] fn test_search(){ let json_value = from_str("{\"dog\":{\"cat\": {\"mouse\" : \"cheese\"}}}").unwrap(); - let found_str = json_value.search(&~"mouse").and_then(|j| j.as_str()); + let found_str = json_value.search(&~"mouse").and_then(|j| j.as_string()); assert!(found_str.is_some()); assert!(found_str.unwrap() == &"cheese"); } @@ -2476,15 +2465,15 @@ mod tests { } #[test] - fn test_is_str(){ + fn test_is_string(){ let json_value = from_str("\"dog\"").unwrap(); - assert!(json_value.is_str()); + assert!(json_value.is_string()); } #[test] - fn test_as_str(){ + fn test_as_string(){ let json_value = from_str("\"dog\"").unwrap(); - let json_str = json_value.as_str(); + let json_str = json_value.as_string(); let expected_str = &"dog"; assert_eq!(json_str, Some(expected_str)); } From e1e4816e16125e27d8bcb0723423b2a8ff21c91c Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Wed, 12 Mar 2014 23:09:03 +1100 Subject: [PATCH 08/12] =?UTF-8?q?rustdoc:=20whitelist=20the=20headers=20th?= =?UTF-8?q?at=20get=20a=20=C2=A7=20on=20hover.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously the :hover rules were making the links to the traits/types in something like impl ... { ... } be displayed with a trailing `§` when hovered over. This commit restricts that behaviour to specific headers, i.e. those that are known to be section headers (like those rendered in markdown doc-comments, and the "Modules", "Functions" etc. headings). --- src/librustdoc/html/markdown.rs | 2 +- src/librustdoc/html/render.rs | 4 +++- src/librustdoc/html/static/main.css | 17 ++++++----------- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 61c1cd734a38d..8780b16918b98 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -209,7 +209,7 @@ pub fn render(w: &mut io::Writer, s: &str, print_toc: bool) -> fmt::Result { }; // Render the HTML - let text = format!(r#"{sec_len,plural,=0{}other{{sec} }}{}"#, s, lvl = level, id = id, sec_len = sec.len(), sec = sec); diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index b705e976e4656..32f83f217c5ba 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1064,7 +1064,9 @@ fn item_module(w: &mut Writer, cx: &Context, clean::ForeignStaticItem(..) => ("ffi-statics", "Foreign Statics"), clean::MacroItem(..) => ("macros", "Macros"), }; - try!(write!(w, "

{name}

\n", + try!(write!(w, + "\n
", id = short, name = name)); } diff --git a/src/librustdoc/html/static/main.css b/src/librustdoc/html/static/main.css index f2c10f053c2f5..2c7e5f0f67510 100644 --- a/src/librustdoc/html/static/main.css +++ b/src/librustdoc/html/static/main.css @@ -317,16 +317,11 @@ pre.rust .doccomment { color: #4D4D4C; } pre.rust .macro, pre.rust .macro-nonterminal { color: #3E999F; } pre.rust .lifetime { color: #B76514; } -h1:hover a:after, -h2:hover a:after, -h3:hover a:after, -h4:hover a:after, -h5:hover a:after, -h6:hover a:after { +h1.section-link:hover a:after, +h2.section-link:hover a:after, +h3.section-link:hover a:after, +h4.section-link:hover a:after, +h5.section-link:hover a:after, +h6.section-link:hover a:after { content: ' § '; } - -h1.fqn:hover a:after, -:hover a.fnname:after { - content: none; -} From f9ecedbc75d5d2d69ba9b98b304b49f4548b2279 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Wed, 12 Mar 2014 23:19:09 +1100 Subject: [PATCH 09/12] docs: add two unlisted libraries to the index page. --- src/doc/index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/doc/index.md b/src/doc/index.md index 8dacf0e4de886..748f3ffb2dc06 100644 --- a/src/doc/index.md +++ b/src/doc/index.md @@ -35,8 +35,10 @@ li {list-style-type: none; } * [The `getopts` argument parsing library](getopts/index.html) * [The `glob` file path matching library](glob/index.html) * [The `green` M:N runtime library](green/index.html) +* [The `hexfloat` library for hexadecimal floating-point literals](hexfloat/index.html) * [The `native` 1:1 threading runtime](native/index.html) * [The `num` arbitrary precision numerics library](num/index.html) +* [The `rand` library for random numbers and distributions](rand/index.html) * [The `rustc` compiler](rustc/index.html) * [The `rustuv` M:N I/O library](rustuv/index.html) * [The `semver` version collation library](semver/index.html) From 167bfaf234b1a477d799c002fa6682040663039c Mon Sep 17 00:00:00 2001 From: Dmitry Promsky Date: Wed, 12 Mar 2014 19:54:43 +0400 Subject: [PATCH 10/12] Added a test that checks that unary structs can be mutably borrowed. Closes #11267 --- src/test/run-pass/issue-11267.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/test/run-pass/issue-11267.rs diff --git a/src/test/run-pass/issue-11267.rs b/src/test/run-pass/issue-11267.rs new file mode 100644 index 0000000000000..15403f5df81f6 --- /dev/null +++ b/src/test/run-pass/issue-11267.rs @@ -0,0 +1,25 @@ +// 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. + +// Tests that unary structs can be mutably borrowed. + +struct Empty; + +impl Iterator for Empty { + fn next(&mut self) -> Option { None } +} + +fn do_something_with(a : &mut Iterator) { + println!("{}", a.next()) +} + +fn main() { + do_something_with(&mut Empty); +} \ No newline at end of file From 1a7e55f4f55d0dd0afdd04bfb2bd0f27ba0b18f4 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 12 Mar 2014 10:35:17 -0700 Subject: [PATCH 11/12] mk: Fix warnings about duplicated rules The footer.tex rule didn't depend on $(1) of the macro it was being defined in, so it was getting duplicated, causing many warnings. --- mk/docs.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mk/docs.mk b/mk/docs.mk index 703c0f4446104..9411957630760 100644 --- a/mk/docs.mk +++ b/mk/docs.mk @@ -147,6 +147,10 @@ SHOULD_BUILD_PDF_DOC_$(1) = 1 endef $(foreach docname,$(PDF_DOCS),$(eval $(call DEF_SHOULD_BUILD_PDF_DOC,$(docname)))) +doc/footer.tex: $(D)/footer.inc | doc/ + @$$(call E, pandoc: $$@) + $$(CFG_PANDOC) --from=html --to=latex $$< --output=$$@ + define DEF_DOC # HTML (rustdoc) @@ -163,10 +167,6 @@ doc/$(1).epub: $$(D)/$(1).md | doc/ @$$(call E, pandoc: $$@) $$(CFG_PANDOC) $$(PANDOC_EPUB_OPTS) $$< --output=$$@ -doc/footer.tex: $(D)/footer.inc | doc/ - @$$(call E, pandoc: $$@) - $$(CFG_PANDOC) --from=html --to=latex $$< --output=$$@ - # PDF (md =(pandoc)=> tex =(pdflatex)=> pdf) DOC_TARGETS += doc/$(1).tex doc/$(1).tex: $$(D)/$(1).md doc/footer.tex doc/version.tex | doc/ From 3f2434eee3f7fa72bf7a8693aef3932d563cf8d5 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 12 Mar 2014 10:31:52 -0700 Subject: [PATCH 12/12] Test fixes from rolling up PRs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #12803 (std: Relax an assertion in oneshot selection) r=brson Closes #12818 (green: Fix a scheduler assertion on yielding) r=brson Closes #12819 (doc: discuss try! in std::io) r=alexcrichton Closes #12820 (Use generic impls for `Hash`) r=alexcrichton Closes #12826 (Remove remaining nolink usages) r=alexcrichton Closes #12835 (Emacs: always jump the cursor if needed on indent) r=brson Closes #12838 (Json method cleanup) r=alexcrichton Closes #12843 (rustdoc: whitelist the headers that get a § on hover) r=alexcrichton Closes #12844 (docs: add two unlisted libraries to the index page) r=pnkfelix Closes #12846 (Added a test that checks that unary structs can be mutably borrowed) r=sfackler Closes #12847 (mk: Fix warnings about duplicated rules) r=nmatsakis --- mk/docs.mk | 4 ++-- src/test/run-pass/issue-11267.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mk/docs.mk b/mk/docs.mk index 9411957630760..5b9e8407a5822 100644 --- a/mk/docs.mk +++ b/mk/docs.mk @@ -148,8 +148,8 @@ endef $(foreach docname,$(PDF_DOCS),$(eval $(call DEF_SHOULD_BUILD_PDF_DOC,$(docname)))) doc/footer.tex: $(D)/footer.inc | doc/ - @$$(call E, pandoc: $$@) - $$(CFG_PANDOC) --from=html --to=latex $$< --output=$$@ + @$(call E, pandoc: $@) + $(CFG_PANDOC) --from=html --to=latex $< --output=$@ define DEF_DOC diff --git a/src/test/run-pass/issue-11267.rs b/src/test/run-pass/issue-11267.rs index 15403f5df81f6..53659a72132ef 100644 --- a/src/test/run-pass/issue-11267.rs +++ b/src/test/run-pass/issue-11267.rs @@ -20,6 +20,6 @@ fn do_something_with(a : &mut Iterator) { println!("{}", a.next()) } -fn main() { +pub fn main() { do_something_with(&mut Empty); -} \ No newline at end of file +}