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 9deccfeb8756..0f78c1971bce 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 75e7265705a7..3c6828fc14fa 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 aae0034263e3..872d6de17582 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 7a18f24140a1..1c10c7b61c36 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 0aace71813eb..28ea36fa2317 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 673eb7e76de4..32de7bf08667 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 5812aaa5038d..6be90c0056d1 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 a3380b5db1d2..f7588f6ca599 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 5b358819e416..6d05001beab9 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 5bd14e717b1b..1900d0ffedd4 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 aa17cd468094..922393d8bb3a 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 d1cef9a06147..9e2b934d0abc 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 e880bd05cf7f..8f4f9259ab7a 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 1351e87c7f64..3e3a94f7f0f6 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 d6f7f58f01c8..73d52654ebf3 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 afd524e9d7af..c602c2fc27f8 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 e529daaa500d..3a86aa3d6b68 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 3102fb2664f7..44b6ecdee707 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 a0c027b2d6b3..0a1b78c8d5d0 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 a1603ee94531..de929b8bfc92 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 940f62789bbc..9a02768faebe 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 b9d8d622731d..7e480f1c32b5 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 977488d4529a..2f5876539413 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 a70fec926594..e242071fb26b 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 350a3d6f4fc2..7c9d2dfa87cd 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 15795f954b8e..e23c970e29a5 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 f2cc2d79a946..30ce77153116 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 63c1a077c8c3..a4e837958c91 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 b304df8f14c1..3a99af3446c2 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 c5d10d25838c..6ce555ba9f74 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 61c1cd734a38..8780b16918b9 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 b705e976e465..32f83f217c5b 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 f2c10f053c2f..2c7e5f0f6751 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 8dacf0e4de88..748f3ffb2dc0 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 000000000000..15403f5df81f --- /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 703c0f444610..941195763076 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 941195763076..5b9e8407a582 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 15403f5df81f..53659a72132e 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 +}