]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #14768 : riccieri/rust/detransmute-arena, r=alexcrichton
authorbors <bors@rust-lang.org>
Wed, 11 Jun 2014 01:07:07 +0000 (18:07 -0700)
committerbors <bors@rust-lang.org>
Wed, 11 Jun 2014 01:07:07 +0000 (18:07 -0700)
**Update**

I've reimplemented this using `Cell` and `RefCell`, as suggested by @alexcrichton. By taking care with the duration of the borrows, I was able to maintain the recursive allocation feature (now covered by a test) without the use of `Unsafe`, and without breaking the non-aliasing `&mut` invariant.

**Original**

Changes both `Arena` and `TypedArena` to contain an inner struct wrapped in a `Unsafe`, and change field access to go through those instead of transmuting `&self` to `&mut self`.

Part of #13933

128 files changed:
src/compiletest/compiletest.rs
src/compiletest/procsrv.rs
src/liballoc/arc.rs
src/libcollections/bitv.rs
src/libcollections/dlist.rs
src/libcollections/priority_queue.rs
src/libcollections/ringbuf.rs
src/libcollections/smallintmap.rs
src/libcollections/treemap.rs
src/libcollections/trie.rs
src/libcore/fmt/mod.rs
src/libcore/result.rs
src/libgetopts/lib.rs
src/libglob/lib.rs
src/libgreen/context.rs
src/libgreen/sched.rs
src/liblibc/lib.rs
src/libnative/io/c_win32.rs
src/libnative/io/file_win32.rs
src/libnative/io/mod.rs
src/libnative/io/net.rs
src/libnative/io/pipe_unix.rs
src/libnative/io/pipe_win32.rs
src/libnative/io/process.rs
src/libnative/task.rs
src/libnum/bigint.rs
src/libnum/integer.rs [new file with mode: 0644]
src/libnum/lib.rs
src/librand/distributions/gamma.rs
src/libregex/compile.rs
src/librustc/driver/mod.rs
src/librustc/front/feature_gate.rs
src/librustc/front/std_inject.rs
src/librustc/metadata/csearch.rs
src/librustc/metadata/decoder.rs
src/librustc/metadata/filesearch.rs
src/librustc/metadata/loader.rs
src/librustc/metadata/tyencode.rs
src/librustc/middle/borrowck/doc.rs
src/librustc/middle/borrowck/gather_loans/lifetime.rs
src/librustc/middle/borrowck/gather_loans/mod.rs
src/librustc/middle/borrowck/gather_loans/restrictions.rs
src/librustc/middle/borrowck/mod.rs
src/librustc/middle/dead.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/graph.rs
src/librustc/middle/liveness.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/privacy.rs
src/librustc/middle/region.rs
src/librustc/middle/resolve.rs
src/librustc/middle/trans/_match.rs
src/librustc/middle/trans/adt.rs
src/librustc/middle/trans/base.rs
src/librustc/middle/trans/common.rs
src/librustc/middle/trans/context.rs
src/librustc/middle/trans/controlflow.rs
src/librustc/middle/trans/debuginfo.rs
src/librustc/middle/trans/foreign.rs
src/librustc/middle/trans/type_.rs
src/librustc/middle/typeck/astconv.rs
src/librustc/middle/typeck/check/mod.rs
src/librustc/middle/typeck/coherence.rs
src/librustc/middle/typeck/collect.rs
src/librustc/middle/typeck/infer/coercion.rs
src/librustc/middle/typeck/infer/combine.rs
src/librustc/middle/typeck/infer/error_reporting.rs
src/librustc/middle/typeck/infer/lattice.rs
src/librustc/middle/typeck/infer/region_inference/doc.rs
src/librustc/middle/typeck/variance.rs
src/librustc/plugin/load.rs
src/librustc/util/common.rs
src/librustc/util/sha2.rs
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.rs
src/librustdoc/flock.rs
src/librustdoc/html/markdown.rs
src/librustdoc/html/toc.rs
src/librustdoc/passes.rs
src/librustdoc/plugins.rs
src/librustdoc/test.rs
src/librustrt/mutex.rs
src/librustrt/task.rs
src/librustrt/unwind.rs
src/librustuv/idle.rs
src/librustuv/lib.rs
src/librustuv/net.rs
src/librustuv/stream.rs
src/librustuv/uvll.rs
src/libstd/collections/hashmap.rs
src/libstd/comm/mod.rs
src/libstd/dynamic_lib.rs [new file with mode: 0644]
src/libstd/io/mod.rs
src/libstd/lib.rs
src/libstd/os.rs
src/libstd/rt/backtrace.rs
src/libstd/task.rs
src/libstd/unstable/dynamic_lib.rs [deleted file]
src/libstd/unstable/mod.rs [deleted file]
src/libsync/lock.rs
src/libsync/one.rs
src/libsync/raw.rs
src/libsyntax/ast.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/deriving/cmp/ord.rs
src/libsyntax/ext/deriving/generic/mod.rs
src/libsyntax/ext/tt/transcribe.rs
src/libsyntax/fold.rs
src/libsyntax/parse/attr.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pp.rs
src/libsyntax/print/pprust.rs
src/libsyntax/visit.rs
src/libterm/terminfo/searcher.rs
src/libtest/lib.rs
src/libuuid/lib.rs
src/test/auxiliary/linkage-visibility.rs
src/test/compile-fail/issue-13446.rs [new file with mode: 0644]
src/test/compile-fail/lint-dead-code-1.rs
src/test/compile-fail/lint-dead-code-4.rs [new file with mode: 0644]
src/test/compile-fail/lint-managed-heap-memory.rs
src/test/compile-fail/lint-owned-heap-memory.rs
src/test/compile-fail/lint-uppercase-variables.rs
src/test/run-make/extern-fn-reachable/main.rs
src/test/run-pass/fn-trait-sugar.rs [new file with mode: 0644]
src/test/run-pass/issue-11940.rs [new file with mode: 0644]
src/test/run-pass/linkage-visibility.rs

index de0ca4971f5c2ba085bd1185dcfa5ed6f3f3d38f..977b7dc32c5658b7d01e9bd4c4b79137bd647bff 100644 (file)
@@ -292,6 +292,7 @@ pub fn test_opts(config: &Config) -> test::TestOpts {
         save_metrics: config.save_metrics.clone(),
         test_shard: config.test_shard.clone(),
         nocapture: false,
+        color: test::AutoColor,
     }
 }
 
index a48a9f1be754133af968a123c297bc9506cb0e2c..8fa34dd6d27c91ff254c139ac6df1c006766842b 100644 (file)
@@ -11,7 +11,7 @@
 use std::os;
 use std::str;
 use std::io::process::{ProcessExit, Command, Process, ProcessOutput};
-use std::unstable::dynamic_lib::DynamicLibrary;
+use std::dynamic_lib::DynamicLibrary;
 
 fn target_env(lib_path: &str, prog: &str) -> Vec<(String, String)> {
     let prog = if cfg!(windows) {prog.slice_to(prog.len() - 4)} else {prog};
index a8eb4b3407eb73fb55baf72a421d72ac9fc87076..5f285010998c8054c9cea0f1c4d5103d6e0dd9c3 100644 (file)
@@ -184,7 +184,7 @@ fn drop(&mut self) {
 
         // This fence is needed to prevent reordering of use of the data and
         // deletion of the data. Because it is marked `Release`, the
-        // decreasing of the reference count sychronizes with this `Acquire`
+        // decreasing of the reference count synchronizes with this `Acquire`
         // fence. This means that use of the data happens before decreasing
         // the refernce count, which happens before this fence, which
         // happens before the deletion of the data.
index 42c8177977057323d89d71363dab68d1defd5390..e100baa1e3ac493bd329842ff40c592cb9d121e2 100644 (file)
@@ -13,6 +13,7 @@
 use core::prelude::*;
 
 use core::cmp;
+use core::default::Default;
 use core::fmt;
 use core::iter::{Enumerate, Repeat, Map, Zip};
 use core::ops;
@@ -698,6 +699,11 @@ pub struct BitvSet {
     bitv: BigBitv
 }
 
+impl Default for BitvSet {
+    #[inline]
+    fn default() -> BitvSet { BitvSet::new() }
+}
+
 impl BitvSet {
     /// Creates a new bit vector set with initially no contents
     pub fn new() -> BitvSet {
index 5a2312456913824a385371596b0b46597620418f..ac8c5c5557ed9cff4921f08afa9e252fddd51fc6 100644 (file)
@@ -24,6 +24,7 @@
 use core::prelude::*;
 
 use alloc::owned::Box;
+use core::default::Default;
 use core::fmt;
 use core::iter;
 use core::mem;
@@ -262,6 +263,11 @@ fn pop_back(&mut self) -> Option<T> {
     }
 }
 
+impl<T> Default for DList<T> {
+    #[inline]
+    fn default() -> DList<T> { DList::new() }
+}
+
 impl<T> DList<T> {
     /// Create an empty DList
     #[inline]
index ea3e7d1747170d0d6a1ba197fc7d61de7069af3f..f25864933f2eba691de2dddcb257aeeb11430c48 100644 (file)
@@ -14,6 +14,7 @@
 
 use core::prelude::*;
 
+use core::default::Default;
 use core::mem::{zeroed, replace, swap};
 use core::ptr;
 
@@ -37,6 +38,11 @@ impl<T: Ord> Mutable for PriorityQueue<T> {
     fn clear(&mut self) { self.data.truncate(0) }
 }
 
+impl<T: Ord> Default for PriorityQueue<T> {
+    #[inline]
+    fn default() -> PriorityQueue<T> { PriorityQueue::new() }
+}
+
 impl<T: Ord> PriorityQueue<T> {
     /// An iterator visiting all values in underlying vector, in
     /// arbitrary order.
index addf73d67a88e7f8e0e2cb804c5f8652710f21f6..ae1925126cae7055f8ef8b2cc0bb8fd395705ed8 100644 (file)
@@ -16,6 +16,7 @@
 use core::prelude::*;
 
 use core::cmp;
+use core::default::Default;
 use core::fmt;
 use core::iter::RandomAccessIterator;
 
@@ -112,6 +113,11 @@ fn push_back(&mut self, t: T) {
     }
 }
 
+impl<T> Default for RingBuf<T> {
+    #[inline]
+    fn default() -> RingBuf<T> { RingBuf::new() }
+}
+
 impl<T> RingBuf<T> {
     /// Create an empty RingBuf
     pub fn new() -> RingBuf<T> {
index cc901864ab532b3eab8bbb9ba95a1ac5527b59e0..6b4982de0821699816e94a85214d2e87681d54cf 100644 (file)
@@ -17,6 +17,7 @@
 
 use core::prelude::*;
 
+use core::default::Default;
 use core::fmt;
 use core::iter::{Enumerate, FilterMap};
 use core::mem::replace;
@@ -114,6 +115,11 @@ fn pop(&mut self, key: &uint) -> Option<V> {
     }
 }
 
+impl<V> Default for SmallIntMap<V> {
+    #[inline]
+    fn default() -> SmallIntMap<V> { SmallIntMap::new() }
+}
+
 impl<V> SmallIntMap<V> {
     /// Create an empty SmallIntMap
     pub fn new() -> SmallIntMap<V> { SmallIntMap{v: vec!()} }
index 489fe60cebf0ec021c8bb744a57dc7ee1be9aa98..1f4ee52008cdc56833056a95fe6288dadb0f8e3c 100644 (file)
@@ -15,6 +15,7 @@
 use core::prelude::*;
 
 use alloc::owned::Box;
+use core::default::Default;
 use core::fmt;
 use core::fmt::Show;
 use core::iter::Peekable;
@@ -135,6 +136,11 @@ fn pop(&mut self, key: &K) -> Option<V> {
     }
 }
 
+impl<K: Ord, V> Default for TreeMap<K,V> {
+    #[inline]
+    fn default() -> TreeMap<K, V> { TreeMap::new() }
+}
+
 impl<K: Ord, V> TreeMap<K, V> {
     /// Create an empty TreeMap
     pub fn new() -> TreeMap<K, V> { TreeMap{root: None, length: 0} }
@@ -633,6 +639,11 @@ fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) }
     fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
 }
 
+impl<T: Ord> Default for TreeSet<T> {
+    #[inline]
+    fn default() -> TreeSet<T> { TreeSet::new() }
+}
+
 impl<T: Ord> TreeSet<T> {
     /// Create an empty TreeSet
     #[inline]
index 6e99d6054a56453b099a1211c8b89c55040be939..3f4fdd66b802accf5b46a9ed5036783a66d5a100 100644 (file)
@@ -13,6 +13,7 @@
 use core::prelude::*;
 
 use alloc::owned::Box;
+use core::default::Default;
 use core::mem::zeroed;
 use core::mem;
 use core::uint;
@@ -105,6 +106,11 @@ fn pop(&mut self, key: &uint) -> Option<T> {
     }
 }
 
+impl<T> Default for TrieMap<T> {
+    #[inline]
+    fn default() -> TrieMap<T> { TrieMap::new() }
+}
+
 impl<T> TrieMap<T> {
     /// Create an empty TrieMap
     #[inline]
@@ -332,6 +338,11 @@ fn remove(&mut self, value: &uint) -> bool {
     }
 }
 
+impl Default for TrieSet {
+    #[inline]
+    fn default() -> TrieSet { TrieSet::new() }
+}
+
 impl TrieSet {
     /// Create an empty TrieSet
     #[inline]
index 37ef325d937e23d789d968c34fc2f06fdf7872fb..91fd183d8c3ac76c03403bc684773d4405e2b67f 100644 (file)
@@ -539,7 +539,7 @@ pub fn pad(&mut self, s: &str) -> Result {
     }
 
     /// Runs a callback, emitting the correct padding either before or
-    /// afterwards depending on whether right or left alingment is requested.
+    /// afterwards depending on whether right or left alignment is requested.
     fn with_padding(&mut self,
                     padding: uint,
                     default: rt::Alignment,
index c19c5d3145ade2d0ecd56f193389a59ee0f937e3..180addfebcfe04f9d1b5525418c91cf306ecf129 100644 (file)
 //! *Note: The actual definition of `Writer` uses `IoResult`, which
 //! is just a synonym for `Result<T, IoError>`.*
 //!
-//! This method doesn`t produce a value, but the write may
+//! This method doesn't produce a value, but the write may
 //! fail. It's crucial to handle the error case, and *not* write
 //! something like this:
 //!
index dec62265516fdb5da21e4285641a8b105300b9e8..eb9c86f00147980ba5f65ee8d420c21505575652 100644 (file)
@@ -163,7 +163,7 @@ pub struct OptGroup {
     pub occur: Occur
 }
 
-/// Describes wether an option is given at all or has a value.
+/// Describes whether an option is given at all or has a value.
 #[deriving(Clone, PartialEq)]
 enum Optval {
     Val(String),
index f3e1da77ce5c773e05801b8e7cf436350343d8a5..6d39a332ad9bd5a3549c7475a9dafa4d0aeb64b8 100644 (file)
@@ -44,7 +44,6 @@
  * pattern - see the `glob` function for more details.
  */
 pub struct Paths {
-    root: Path,
     dir_patterns: Vec<Pattern>,
     require_dir: bool,
     options: MatchOptions,
@@ -108,7 +107,6 @@ fn check_windows_verbatim(_: &Path) -> bool { false }
             // FIXME: How do we want to handle verbatim paths? I'm inclined to return nothing,
             // since we can't very well find all UNC shares with a 1-letter server name.
             return Paths {
-                root: root,
                 dir_patterns: Vec::new(),
                 require_dir: false,
                 options: options,
@@ -134,7 +132,6 @@ fn check_windows_verbatim(_: &Path) -> bool { false }
     }
 
     Paths {
-        root: root,
         dir_patterns: dir_patterns,
         require_dir: require_dir,
         options: options,
index 5b1a4a8b80ec0e2394b665390584a9ab9c56740c..9071656f21334c896c60c0891977cf0f8196047a 100644 (file)
@@ -143,6 +143,7 @@ pub fn swap(out_context: &mut Context, in_context: &Context) {
 // stacks are disabled.
 
 #[cfg(target_arch = "x86")]
+#[repr(C)]
 struct Registers {
     eax: u32, ebx: u32, ecx: u32, edx: u32,
     ebp: u32, esi: u32, edi: u32, esp: u32,
@@ -226,7 +227,7 @@ fn initialize_call_frame(regs: &mut Registers, fptr: InitFn, arg: uint,
     regs[RUSTRT_R14] = procedure.env as uint;
     regs[RUSTRT_R15] = fptr as uint;
 
-    // These registers are picked up by the regulard context switch paths. These
+    // These registers are picked up by the regular context switch paths. These
     // will put us in "mostly the right context" except for frobbing all the
     // arguments to the right place. We have the small trampoline code inside of
     // rust_bootstrap_green_task to do that.
index f55dc92eac610c5d58240a93bf8f0b9c43defdd1..1e8f774ea16832d7e6e8c5aace2797d304ac9998 100644 (file)
@@ -82,7 +82,7 @@ pub struct Scheduler {
     run_anything: bool,
     /// A fast XorShift rng for scheduler use
     rng: XorShiftRng,
-    /// A togglable idle callback
+    /// A toggleable idle callback
     idle_callback: Option<Box<PausableIdleCallback:Send>>,
     /// A countdown that starts at a random value and is decremented
     /// every time a yield check is performed. When it hits 0 a task
@@ -287,7 +287,7 @@ fn run_sched_once(mut ~self, stask: Box<GreenTask>) {
 
         // After processing a message, we consider doing some more work on the
         // event loop. The "keep going" condition changes after the first
-        // iteration becase we don't want to spin here infinitely.
+        // iteration because we don't want to spin here infinitely.
         //
         // Once we start doing work we can keep doing work so long as the
         // iteration does something. Note that we don't want to starve the
index b833b2a65158d90b26db3ad51b7beb9b411b7d07..ff87b7fb0074bb2d0d08aa32d2b24ab743b8e842 100644 (file)
 extern {}
 
 /// A wrapper for a nullable pointer. Don't use this except for interacting
-/// with libc. Basically Option, but without the dependance on libstd.
+/// with libc. Basically Option, but without the dependence on libstd.
 // If/when libprim happens, this can be removed in favor of that
 pub enum Nullable<T> {
     Null,
@@ -3497,7 +3497,7 @@ pub mod sysconf {
 
 
 pub mod funcs {
-    // Thankfull most of c95 is universally available and does not vary by OS
+    // Thankfully most of c95 is universally available and does not vary by OS
     // or anything. The same is not true of POSIX.
 
     pub mod c95 {
index 93b3ec7ccefbf204f1b1d8ea9c31dc7013440271..e855b8bd4f2647f6efa983d526eb21d3f106e1c2 100644 (file)
@@ -20,6 +20,7 @@
 static FD_SETSIZE: uint = 64;
 pub static MSG_DONTWAIT: libc::c_int = 0;
 
+#[repr(C)]
 pub struct WSADATA {
     pub wVersion: libc::WORD,
     pub wHighVersion: libc::WORD,
@@ -32,6 +33,7 @@ pub struct WSADATA {
 
 pub type LPWSADATA = *mut WSADATA;
 
+#[repr(C)]
 pub struct fd_set {
     fd_count: libc::c_uint,
     fd_array: [libc::SOCKET, ..FD_SETSIZE],
@@ -69,7 +71,6 @@ pub fn CancelIoEx(hFile: libc::HANDLE,
 pub mod compat {
     use std::intrinsics::{atomic_store_relaxed, transmute};
     use libc::types::os::arch::extra::{LPCWSTR, HMODULE, LPCSTR, LPVOID};
-    use std::os::win32::as_utf16_p;
 
     extern "system" {
         fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
@@ -80,12 +81,11 @@ pub mod compat {
     // This way, calling a function in this compatibility layer (after it's loaded) shouldn't
     // be any slower than a regular DLL call.
     unsafe fn store_func<T: Copy>(ptr: *mut T, module: &str, symbol: &str, fallback: T) {
-        as_utf16_p(module, |module| {
-            symbol.with_c_str(|symbol| {
-                let handle = GetModuleHandleW(module);
-                let func: Option<T> = transmute(GetProcAddress(handle, symbol));
-                atomic_store_relaxed(ptr, func.unwrap_or(fallback))
-            })
+        let module = module.to_utf16().append_one(0);
+        symbol.with_c_str(|symbol| {
+            let handle = GetModuleHandleW(module.as_ptr());
+            let func: Option<T> = transmute(GetProcAddress(handle, symbol));
+            atomic_store_relaxed(ptr, func.unwrap_or(fallback))
         })
     }
 
index 2a5b78e55067cb75e5ef369981b210157f6f2309..5ace8e347c67ef7d5c4e521f91ec125d5314d908 100644 (file)
 use libc;
 use std::c_str::CString;
 use std::mem;
-use std::os::win32::{as_utf16_p, fill_utf16_buf_and_decode};
+use std::os::win32::fill_utf16_buf_and_decode;
 use std::ptr;
 use std::rt::rtio;
-use std::rt::rtio::IoResult;
+use std::rt::rtio::{IoResult, IoError};
 use std::str;
 use std::vec;
 
@@ -253,6 +253,17 @@ fn drop(&mut self) {
     }
 }
 
+pub fn to_utf16(s: &CString) -> IoResult<Vec<u16>> {
+    match s.as_str() {
+        Some(s) => Ok(s.to_utf16().append_one(0)),
+        None => Err(IoError {
+            code: libc::ERROR_INVALID_NAME as uint,
+            extra: 0,
+            detail: Some("valid unicode input required".to_str()),
+        })
+    }
+}
+
 pub fn open(path: &CString, fm: rtio::FileMode, fa: rtio::FileAccess)
         -> IoResult<FileDesc> {
     // Flags passed to open_osfhandle
@@ -299,15 +310,16 @@ pub fn open(path: &CString, fm: rtio::FileMode, fa: rtio::FileAccess)
     // Compat with unix, this allows opening directories (see libuv)
     dwFlagsAndAttributes |= libc::FILE_FLAG_BACKUP_SEMANTICS;
 
-    let handle = as_utf16_p(path.as_str().unwrap(), |buf| unsafe {
-        libc::CreateFileW(buf,
+    let path = try!(to_utf16(path));
+    let handle = unsafe {
+        libc::CreateFileW(path.as_ptr(),
                           dwDesiredAccess,
                           dwShareMode,
                           ptr::mut_null(),
                           dwCreationDisposition,
                           dwFlagsAndAttributes,
                           ptr::mut_null())
-    });
+    };
     if handle == libc::INVALID_HANDLE_VALUE as libc::HANDLE {
         Err(super::last_error())
     } else {
@@ -324,11 +336,10 @@ pub fn open(path: &CString, fm: rtio::FileMode, fa: rtio::FileAccess)
 }
 
 pub fn mkdir(p: &CString, _mode: uint) -> IoResult<()> {
+    let p = try!(to_utf16(p));
     super::mkerr_winbool(unsafe {
         // FIXME: turn mode into something useful? #2623
-        as_utf16_p(p.as_str().unwrap(), |buf| {
-            libc::CreateDirectoryW(buf, ptr::mut_null())
-        })
+        libc::CreateDirectoryW(p.as_ptr(), ptr::mut_null())
     })
 }
 
@@ -351,9 +362,11 @@ fn prune(root: &CString, dirs: Vec<Path>) -> Vec<CString> {
     let star = Path::new(unsafe {
         CString::new(p.with_ref(|p| p), false)
     }).join("*");
-    as_utf16_p(star.as_str().unwrap(), |path_ptr| unsafe {
+    let path = try!(to_utf16(&star.to_c_str()));
+
+    unsafe {
         let wfd_ptr = malloc_raw(rust_list_dir_wfd_size() as uint);
-        let find_handle = libc::FindFirstFileW(path_ptr, wfd_ptr as libc::HANDLE);
+        let find_handle = libc::FindFirstFileW(path.as_ptr(), wfd_ptr as libc::HANDLE);
         if find_handle as libc::c_int != libc::INVALID_HANDLE_VALUE {
             let mut paths = vec!();
             let mut more_files = 1 as libc::c_int;
@@ -377,37 +390,35 @@ fn prune(root: &CString, dirs: Vec<Path>) -> Vec<CString> {
         } else {
             Err(super::last_error())
         }
-    })
+    }
 }
 
 pub fn unlink(p: &CString) -> IoResult<()> {
+    let p = try!(to_utf16(p));
     super::mkerr_winbool(unsafe {
-        as_utf16_p(p.as_str().unwrap(), |buf| {
-            libc::DeleteFileW(buf)
-        })
+        libc::DeleteFileW(p.as_ptr())
     })
 }
 
 pub fn rename(old: &CString, new: &CString) -> IoResult<()> {
+    let old = try!(to_utf16(old));
+    let new = try!(to_utf16(new));
     super::mkerr_winbool(unsafe {
-        as_utf16_p(old.as_str().unwrap(), |old| {
-            as_utf16_p(new.as_str().unwrap(), |new| {
-                libc::MoveFileExW(old, new, libc::MOVEFILE_REPLACE_EXISTING)
-            })
-        })
+        libc::MoveFileExW(old.as_ptr(), new.as_ptr(),
+                          libc::MOVEFILE_REPLACE_EXISTING)
     })
 }
 
 pub fn chmod(p: &CString, mode: uint) -> IoResult<()> {
-    super::mkerr_libc(as_utf16_p(p.as_str().unwrap(), |p| unsafe {
-        libc::wchmod(p, mode as libc::c_int)
-    }))
+    let p = try!(to_utf16(p));
+    super::mkerr_libc(unsafe {
+        libc::wchmod(p.as_ptr(), mode as libc::c_int)
+    })
 }
 
 pub fn rmdir(p: &CString) -> IoResult<()> {
-    super::mkerr_libc(as_utf16_p(p.as_str().unwrap(), |p| unsafe {
-        libc::wrmdir(p)
-    }))
+    let p = try!(to_utf16(p));
+    super::mkerr_libc(unsafe { libc::wrmdir(p.as_ptr()) })
 }
 
 pub fn chown(_p: &CString, _uid: int, _gid: int) -> IoResult<()> {
@@ -418,16 +429,15 @@ pub fn chown(_p: &CString, _uid: int, _gid: int) -> IoResult<()> {
 pub fn readlink(p: &CString) -> IoResult<CString> {
     // FIXME: I have a feeling that this reads intermediate symlinks as well.
     use io::c::compat::kernel32::GetFinalPathNameByHandleW;
+    let p = try!(to_utf16(p));
     let handle = unsafe {
-        as_utf16_p(p.as_str().unwrap(), |p| {
-            libc::CreateFileW(p,
-                              libc::GENERIC_READ,
-                              libc::FILE_SHARE_READ,
-                              ptr::mut_null(),
-                              libc::OPEN_EXISTING,
-                              libc::FILE_ATTRIBUTE_NORMAL,
-                              ptr::mut_null())
-        })
+        libc::CreateFileW(p.as_ptr(),
+                          libc::GENERIC_READ,
+                          libc::FILE_SHARE_READ,
+                          ptr::mut_null(),
+                          libc::OPEN_EXISTING,
+                          libc::FILE_ATTRIBUTE_NORMAL,
+                          ptr::mut_null())
     };
     if handle as int == libc::INVALID_HANDLE_VALUE as int {
         return Err(super::last_error())
@@ -453,19 +463,19 @@ pub fn readlink(p: &CString) -> IoResult<CString> {
 
 pub fn symlink(src: &CString, dst: &CString) -> IoResult<()> {
     use io::c::compat::kernel32::CreateSymbolicLinkW;
-    super::mkerr_winbool(as_utf16_p(src.as_str().unwrap(), |src| {
-        as_utf16_p(dst.as_str().unwrap(), |dst| {
-            unsafe { CreateSymbolicLinkW(dst, src, 0) }
-        }) as libc::BOOL
-    }))
+    let src = try!(to_utf16(src));
+    let dst = try!(to_utf16(dst));
+    super::mkerr_winbool(unsafe {
+        CreateSymbolicLinkW(dst.as_ptr(), src.as_ptr(), 0) as libc::BOOL
+    })
 }
 
 pub fn link(src: &CString, dst: &CString) -> IoResult<()> {
-    super::mkerr_winbool(as_utf16_p(src.as_str().unwrap(), |src| {
-        as_utf16_p(dst.as_str().unwrap(), |dst| {
-            unsafe { libc::CreateHardLinkW(dst, src, ptr::mut_null()) }
-        })
-    }))
+    let src = try!(to_utf16(src));
+    let dst = try!(to_utf16(dst));
+    super::mkerr_winbool(unsafe {
+        libc::CreateHardLinkW(dst.as_ptr(), src.as_ptr(), ptr::mut_null())
+    })
 }
 
 fn mkstat(stat: &libc::stat) -> rtio::FileStat {
@@ -491,12 +501,11 @@ fn mkstat(stat: &libc::stat) -> rtio::FileStat {
 
 pub fn stat(p: &CString) -> IoResult<rtio::FileStat> {
     let mut stat: libc::stat = unsafe { mem::zeroed() };
-    as_utf16_p(p.as_str().unwrap(), |up| {
-        match unsafe { libc::wstat(up, &mut stat) } {
-            0 => Ok(mkstat(&stat)),
-            _ => Err(super::last_error()),
-        }
-    })
+    let p = try!(to_utf16(p));
+    match unsafe { libc::wstat(p.as_ptr(), &mut stat) } {
+        0 => Ok(mkstat(&stat)),
+        _ => Err(super::last_error()),
+    }
 }
 
 pub fn lstat(_p: &CString) -> IoResult<rtio::FileStat> {
@@ -509,7 +518,8 @@ pub fn utime(p: &CString, atime: u64, mtime: u64) -> IoResult<()> {
         actime: (atime / 1000) as libc::time64_t,
         modtime: (mtime / 1000) as libc::time64_t,
     };
-    super::mkerr_libc(as_utf16_p(p.as_str().unwrap(), |p| unsafe {
-        libc::wutime(p, &buf)
-    }))
+    let p = try!(to_utf16(p));
+    super::mkerr_libc(unsafe {
+        libc::wutime(p.as_ptr(), &buf)
+    })
 }
index 3b0dbe2d0dce978e63be79d4c53ef6cdfd302e2a..4158db7bb8ea1d902ef8fe40e67a1596f4d7d60c 100644 (file)
@@ -77,7 +77,7 @@ fn unimpl() -> IoError {
     IoError {
         code: ERROR as uint,
         extra: 0,
-        detail: None,
+        detail: Some("not yet supported by the `native` runtime, maybe try `green`.".to_string()),
     }
 }
 
@@ -152,13 +152,13 @@ fn keep_going(data: &[u8], f: |*u8, uint| -> i64) -> i64 {
 /// Implementation of rt::rtio's IoFactory trait to generate handles to the
 /// native I/O functionality.
 pub struct IoFactory {
-    cannot_construct_outside_of_this_module: ()
+    _cannot_construct_outside_of_this_module: ()
 }
 
 impl IoFactory {
     pub fn new() -> IoFactory {
         net::init();
-        IoFactory { cannot_construct_outside_of_this_module: () }
+        IoFactory { _cannot_construct_outside_of_this_module: () }
     }
 }
 
index 24956e514ec83e09cb85ce4234040e270ad2d03d..e7effbd6bdbfb064ba935408f9cd0fc9a932b86d 100644 (file)
@@ -254,7 +254,10 @@ pub struct TcpStream {
 
 struct Inner {
     fd: sock_t,
-    lock: mutex::NativeMutex,
+
+    // Unused on Linux, where this lock is not necessary.
+    #[allow(dead_code)]
+    lock: mutex::NativeMutex
 }
 
 pub struct Guard<'a> {
index 7a1134fbe5956109bed023e09ad0e6997ce1b0d8..1458b475ae9598729e4cc700ae52f7ea515f8800 100644 (file)
@@ -58,7 +58,10 @@ fn addr_to_sockaddr_un(addr: &CString) -> IoResult<(libc::sockaddr_storage, uint
 
 struct Inner {
     fd: fd_t,
-    lock: mutex::NativeMutex,
+
+    // Unused on Linux, where this lock is not necessary.
+    #[allow(dead_code)]
+    lock: mutex::NativeMutex
 }
 
 impl Inner {
index a5694436b97200016f91a4d4463493a7029b6531..b097bde2ad8d0d22b2a1e42cff7e424f749d4375 100644 (file)
@@ -50,7 +50,7 @@
 //! it sounded like named pipes just weren't built for this kind of interaction,
 //! and the suggested solution was to use overlapped I/O.
 //!
-//! I don't realy know what overlapped I/O is, but my basic understanding after
+//! I don't really know what overlapped I/O is, but my basic understanding after
 //! reading about it is that you have an external Event which is used to signal
 //! I/O completion, passed around in some OVERLAPPED structures. As to what this
 //! is, I'm not exactly sure.
@@ -88,7 +88,6 @@
 use libc;
 use std::c_str::CString;
 use std::mem;
-use std::os::win32::as_utf16_p;
 use std::os;
 use std::ptr;
 use std::rt::rtio;
@@ -98,6 +97,7 @@
 
 use super::c;
 use super::util;
+use super::file::to_utf16;
 
 struct Event(libc::HANDLE);
 
@@ -261,67 +261,66 @@ fn try_connect(p: *u16) -> Option<libc::HANDLE> {
     }
 
     pub fn connect(addr: &CString, timeout: Option<u64>) -> IoResult<UnixStream> {
-        as_utf16_p(addr.as_str().unwrap(), |p| {
-            let start = ::io::timer::now();
-            loop {
-                match UnixStream::try_connect(p) {
-                    Some(handle) => {
-                        let inner = Inner::new(handle);
-                        let mut mode = libc::PIPE_TYPE_BYTE |
-                                       libc::PIPE_READMODE_BYTE |
-                                       libc::PIPE_WAIT;
-                        let ret = unsafe {
-                            libc::SetNamedPipeHandleState(inner.handle,
-                                                          &mut mode,
-                                                          ptr::mut_null(),
-                                                          ptr::mut_null())
-                        };
-                        return if ret == 0 {
-                            Err(super::last_error())
-                        } else {
-                            Ok(UnixStream {
-                                inner: Arc::new(inner),
-                                read: None,
-                                write: None,
-                                read_deadline: 0,
-                                write_deadline: 0,
-                            })
-                        }
+        let addr = try!(to_utf16(addr));
+        let start = ::io::timer::now();
+        loop {
+            match UnixStream::try_connect(addr.as_ptr()) {
+                Some(handle) => {
+                    let inner = Inner::new(handle);
+                    let mut mode = libc::PIPE_TYPE_BYTE |
+                                   libc::PIPE_READMODE_BYTE |
+                                   libc::PIPE_WAIT;
+                    let ret = unsafe {
+                        libc::SetNamedPipeHandleState(inner.handle,
+                                                      &mut mode,
+                                                      ptr::mut_null(),
+                                                      ptr::mut_null())
+                    };
+                    return if ret == 0 {
+                        Err(super::last_error())
+                    } else {
+                        Ok(UnixStream {
+                            inner: Arc::new(inner),
+                            read: None,
+                            write: None,
+                            read_deadline: 0,
+                            write_deadline: 0,
+                        })
                     }
-                    None => {}
                 }
+                None => {}
+            }
 
-                // On windows, if you fail to connect, you may need to call the
-                // `WaitNamedPipe` function, and this is indicated with an error
-                // code of ERROR_PIPE_BUSY.
-                let code = unsafe { libc::GetLastError() };
-                if code as int != libc::ERROR_PIPE_BUSY as int {
-                    return Err(super::last_error())
-                }
+            // On windows, if you fail to connect, you may need to call the
+            // `WaitNamedPipe` function, and this is indicated with an error
+            // code of ERROR_PIPE_BUSY.
+            let code = unsafe { libc::GetLastError() };
+            if code as int != libc::ERROR_PIPE_BUSY as int {
+                return Err(super::last_error())
+            }
 
-                match timeout {
-                    Some(timeout) => {
-                        let now = ::io::timer::now();
-                        let timed_out = (now - start) >= timeout || unsafe {
-                            let ms = (timeout - (now - start)) as libc::DWORD;
-                            libc::WaitNamedPipeW(p, ms) == 0
-                        };
-                        if timed_out {
-                            return Err(util::timeout("connect timed out"))
-                        }
+            match timeout {
+                Some(timeout) => {
+                    let now = ::io::timer::now();
+                    let timed_out = (now - start) >= timeout || unsafe {
+                        let ms = (timeout - (now - start)) as libc::DWORD;
+                        libc::WaitNamedPipeW(addr.as_ptr(), ms) == 0
+                    };
+                    if timed_out {
+                        return Err(util::timeout("connect timed out"))
                     }
+                }
 
-                    // An example I found on microsoft's website used 20
-                    // seconds, libuv uses 30 seconds, hence we make the
-                    // obvious choice of waiting for 25 seconds.
-                    None => {
-                        if unsafe { libc::WaitNamedPipeW(p, 25000) } == 0 {
-                            return Err(super::last_error())
-                        }
+                // An example I found on microsoft's website used 20
+                // seconds, libuv uses 30 seconds, hence we make the
+                // obvious choice of waiting for 25 seconds.
+                None => {
+                    if unsafe { libc::WaitNamedPipeW(addr.as_ptr(), 25000) } == 0 {
+                        return Err(super::last_error())
                     }
                 }
             }
-        })
+        }
     }
 
     fn handle(&self) -> libc::HANDLE { self.inner.handle }
@@ -564,14 +563,13 @@ pub fn bind(addr: &CString) -> IoResult<UnixListener> {
         // Although we technically don't need the pipe until much later, we
         // create the initial handle up front to test the validity of the name
         // and such.
-        as_utf16_p(addr.as_str().unwrap(), |p| {
-            let ret = unsafe { pipe(p, true) };
-            if ret == libc::INVALID_HANDLE_VALUE as libc::HANDLE {
-                Err(super::last_error())
-            } else {
-                Ok(UnixListener { handle: ret, name: addr.clone() })
-            }
-        })
+        let addr_v = try!(to_utf16(addr));
+        let ret = unsafe { pipe(addr_v.as_ptr(), true) };
+        if ret == libc::INVALID_HANDLE_VALUE as libc::HANDLE {
+            Err(super::last_error())
+        } else {
+            Ok(UnixListener { handle: ret, name: addr.clone() })
+        }
     }
 
     pub fn native_listen(self) -> IoResult<UnixAcceptor> {
@@ -639,6 +637,8 @@ pub fn native_accept(&mut self) -> IoResult<UnixStream> {
         // using the original server pipe.
         let handle = self.listener.handle;
 
+        let name = try!(to_utf16(&self.listener.name));
+
         // Once we've got a "server handle", we need to wait for a client to
         // connect. The ConnectNamedPipe function will block this thread until
         // someone on the other end connects. This function can "fail" if a
@@ -678,9 +678,7 @@ pub fn native_accept(&mut self) -> IoResult<UnixStream> {
         // Now that we've got a connected client to our handle, we need to
         // create a second server pipe. If this fails, we disconnect the
         // connected client and return an error (see comments above).
-        let new_handle = as_utf16_p(self.listener.name.as_str().unwrap(), |p| {
-            unsafe { pipe(p, false) }
-        });
+        let new_handle = unsafe { pipe(name.as_ptr(), false) };
         if new_handle == libc::INVALID_HANDLE_VALUE as libc::HANDLE {
             let ret = Err(super::last_error());
             // If our disconnection fails, then there's not really a whole lot
index 2c2b7cec1dec4806a3d32835de56b458b825d85f..d8486cb9f0942c64cf7b101affebf09f7bb66d2d 100644 (file)
@@ -296,16 +296,15 @@ fn spawn_process_os(cfg: ProcessConfig,
                     lpSecurityDescriptor: ptr::mut_null(),
                     bInheritHandle: 1,
                 };
-                *slot = os::win32::as_utf16_p("NUL", |filename| {
-                    libc::CreateFileW(filename,
-                                      access,
-                                      libc::FILE_SHARE_READ |
-                                          libc::FILE_SHARE_WRITE,
-                                      &mut sa,
-                                      libc::OPEN_EXISTING,
-                                      0,
-                                      ptr::mut_null())
-                });
+                let filename = "NUL".to_utf16().append_one(0);
+                *slot = libc::CreateFileW(filename.as_ptr(),
+                                          access,
+                                          libc::FILE_SHARE_READ |
+                                              libc::FILE_SHARE_WRITE,
+                                          &mut sa,
+                                          libc::OPEN_EXISTING,
+                                          0,
+                                          ptr::mut_null());
                 if *slot == INVALID_HANDLE_VALUE as libc::HANDLE {
                     return Err(super::last_error())
                 }
@@ -338,18 +337,17 @@ fn spawn_process_os(cfg: ProcessConfig,
 
         with_envp(cfg.env, |envp| {
             with_dirp(cfg.cwd, |dirp| {
-                os::win32::as_mut_utf16_p(cmd_str.as_slice(), |cmdp| {
-                    let created = CreateProcessW(ptr::null(),
-                                                 cmdp,
-                                                 ptr::mut_null(),
-                                                 ptr::mut_null(),
-                                                 TRUE,
-                                                 flags, envp, dirp,
-                                                 &mut si, &mut pi);
-                    if created == FALSE {
-                        create_err = Some(super::last_error());
-                    }
-                })
+                let mut cmd_str = cmd_str.to_utf16().append_one(0);
+                let created = CreateProcessW(ptr::null(),
+                                             cmd_str.as_mut_ptr(),
+                                             ptr::mut_null(),
+                                             ptr::mut_null(),
+                                             TRUE,
+                                             flags, envp, dirp,
+                                             &mut si, &mut pi);
+                if created == FALSE {
+                    create_err = Some(super::last_error());
+                }
             })
         });
 
@@ -740,7 +738,8 @@ fn with_dirp<T>(d: Option<&CString>, cb: |*u16| -> T) -> T {
       Some(dir) => {
           let dir_str = dir.as_str()
                            .expect("expected workingdirectory to be utf-8 encoded");
-          os::win32::as_utf16_p(dir_str, cb)
+          let dir_str = dir_str.to_utf16().append_one(0);
+          cb(dir_str.as_ptr())
       },
       None => cb(ptr::null())
     }
@@ -924,7 +923,7 @@ fn waitpid(pid: pid_t, deadline: u64) -> IoResult<rtio::ProcessExit> {
     // Register a new SIGCHLD handler, returning the reading half of the
     // self-pipe plus the old handler registered (return value of sigaction).
     //
-    // Be sure to set up the self-pipe first because as soon as we reigster a
+    // Be sure to set up the self-pipe first because as soon as we register a
     // handler we're going to start receiving signals.
     fn register_sigchld() -> (libc::c_int, c::sigaction) {
         unsafe {
index f16c41d4e28f7c1806cda0089d22b7b57447e7ee..b073c2c7fbf026f8ecfe52b3a1065279315c3bb7 100644 (file)
@@ -166,7 +166,7 @@ fn can_block(&self) -> bool { true }
     //
     // On a mildly unrelated note, it should also be pointed out that OS
     // condition variables are susceptible to spurious wakeups, which we need to
-    // be ready for. In order to accomodate for this fact, we have an extra
+    // be ready for. In order to accommodate for this fact, we have an extra
     // `awoken` field which indicates whether we were actually woken up via some
     // invocation of `reawaken`. This flag is only ever accessed inside the
     // lock, so there's no need to make it atomic.
index 67501c9795d18fda7fdc10eb46075db760a507a0..0933301970d1969a3901a1c9f6b196107653e7b4 100644 (file)
 */
 
 use Integer;
+use rand::Rng;
 
-use std::cmp;
+use std::{cmp, fmt};
 use std::default::Default;
-use std::fmt;
 use std::from_str::FromStr;
 use std::num::CheckedDiv;
 use std::num::{Bitwise, ToPrimitive, FromPrimitive};
 use std::num::{Zero, One, ToStrRadix, FromStrRadix};
-use rand::Rng;
 use std::string::String;
-use std::uint;
-use std::{i64, u64};
+use std::{uint, i64, u64};
 
 /**
 A `BigDigit` is a `BigUint`'s composing element.
@@ -94,7 +92,7 @@ impl Eq for BigUint {}
 impl PartialOrd for BigUint {
     #[inline]
     fn lt(&self, other: &BigUint) -> bool {
-        match self.cmp(other) { Less => true, _ => false}
+        self.cmp(other) == Less
     }
 }
 
@@ -115,7 +113,7 @@ fn cmp(&self, other: &BigUint) -> Ordering {
 
 impl Default for BigUint {
     #[inline]
-    fn default() -> BigUint { BigUint::new(Vec::new()) }
+    fn default() -> BigUint { Zero::zero() }
 }
 
 impl fmt::Show for BigUint {
@@ -605,7 +603,7 @@ fn to_biguint(&self) -> Option<BigUint> {
 
 impl ToStrRadix for BigUint {
     fn to_str_radix(&self, radix: uint) -> String {
-        assert!(1 < radix && radix <= 16);
+        assert!(1 < radix && radix <= 16, "The radix must be within (1, 16]");
         let (base, max_len) = get_radix_base(radix);
         if base == BigDigit::base {
             return fill_concat(self.data.as_slice(), radix, max_len)
@@ -645,8 +643,7 @@ fn fill_concat(v: &[BigDigit], radix: uint, l: uint) -> String {
 impl FromStrRadix for BigUint {
     /// Creates and initializes a `BigUint`.
     #[inline]
-    fn from_str_radix(s: &str, radix: uint)
-        -> Option<BigUint> {
+    fn from_str_radix(s: &str, radix: uint) -> Option<BigUint> {
         BigUint::parse_bytes(s.as_bytes(), radix)
     }
 }
@@ -656,14 +653,11 @@ impl BigUint {
     ///
     /// The digits are be in base 2^32.
     #[inline]
-    pub fn new(v: Vec<BigDigit>) -> BigUint {
+    pub fn new(mut digits: Vec<BigDigit>) -> BigUint {
         // omit trailing zeros
-        let new_len = v.iter().rposition(|n| *n != 0).map_or(0, |p| p + 1);
-
-        if new_len == v.len() { return BigUint { data: v }; }
-        let mut v = v;
-        v.truncate(new_len);
-        return BigUint { data: v };
+        let new_len = digits.iter().rposition(|n| *n != 0).map_or(0, |p| p + 1);
+        digits.truncate(new_len);
+        BigUint { data: digits }
     }
 
     /// Creates and initializes a `BigUint`.
@@ -671,7 +665,7 @@ pub fn new(v: Vec<BigDigit>) -> BigUint {
     /// The digits are be in base 2^32.
     #[inline]
     pub fn from_slice(slice: &[BigDigit]) -> BigUint {
-        return BigUint::new(Vec::from_slice(slice));
+        BigUint::new(Vec::from_slice(slice))
     }
 
     /// Creates and initializes a `BigUint`.
@@ -768,7 +762,6 @@ pub fn bits(&self) -> uint {
 // `DoubleBigDigit` size dependent
 #[inline]
 fn get_radix_base(radix: uint) -> (DoubleBigDigit, uint) {
-    assert!(1 < radix && radix <= 16);
     match radix {
         2  => (4294967296, 32),
         3  => (3486784401, 20),
@@ -785,7 +778,7 @@ fn get_radix_base(radix: uint) -> (DoubleBigDigit, uint) {
         14 => (1475789056, 8),
         15 => (2562890625, 8),
         16 => (4294967296, 8),
-        _  => fail!()
+        _  => fail!("The radix must be within (1, 16]")
     }
 }
 
@@ -815,7 +808,7 @@ pub struct BigInt {
 impl PartialEq for BigInt {
     #[inline]
     fn eq(&self, other: &BigInt) -> bool {
-        match self.cmp(other) { Equal => true, _ => false }
+        self.cmp(other) == Equal
     }
 }
 
@@ -824,7 +817,7 @@ impl Eq for BigInt {}
 impl PartialOrd for BigInt {
     #[inline]
     fn lt(&self, other: &BigInt) -> bool {
-        match self.cmp(other) { Less => true, _ => false}
+        self.cmp(other) == Less
     }
 }
 
@@ -844,7 +837,7 @@ fn cmp(&self, other: &BigInt) -> Ordering {
 
 impl Default for BigInt {
     #[inline]
-    fn default() -> BigInt { BigInt::new(Zero, Vec::new()) }
+    fn default() -> BigInt { Zero::zero() }
 }
 
 impl fmt::Show for BigInt {
@@ -929,8 +922,7 @@ fn add(&self, other: &BigInt) -> BigInt {
         match (self.sign, other.sign) {
             (Zero, _)      => other.clone(),
             (_,    Zero)   => self.clone(),
-            (Plus, Plus)   => BigInt::from_biguint(Plus,
-                                                   self.data + other.data),
+            (Plus, Plus)   => BigInt::from_biguint(Plus, self.data + other.data),
             (Plus, Minus)  => self - (-*other),
             (Minus, Plus)  => other - (-*self),
             (Minus, Minus) => -((-self) + (-*other))
@@ -975,7 +967,7 @@ impl Div<BigInt, BigInt> for BigInt {
     #[inline]
     fn div(&self, other: &BigInt) -> BigInt {
         let (q, _) = self.div_rem(other);
-        return q;
+        q
     }
 }
 
@@ -983,7 +975,7 @@ impl Rem<BigInt, BigInt> for BigInt {
     #[inline]
     fn rem(&self, other: &BigInt) -> BigInt {
         let (_, r) = self.div_rem(other);
-        return r;
+        r
     }
 }
 
@@ -1045,13 +1037,13 @@ fn div_rem(&self, other: &BigInt) -> (BigInt, BigInt) {
     #[inline]
     fn div_floor(&self, other: &BigInt) -> BigInt {
         let (d, _) = self.div_mod_floor(other);
-        return d;
+        d
     }
 
     #[inline]
     fn mod_floor(&self, other: &BigInt) -> BigInt {
         let (_, m) = self.div_mod_floor(other);
-        return m;
+        m
     }
 
     fn div_mod_floor(&self, other: &BigInt) -> (BigInt, BigInt) {
@@ -1265,7 +1257,7 @@ fn gen_biguint(&mut self, bit_size: uint) -> BigUint {
             let final_digit: BigDigit = self.gen();
             data.push(final_digit >> (BigDigit::bits - rem));
         }
-        return BigUint::new(data);
+        BigUint::new(data)
     }
 
     fn gen_bigint(&mut self, bit_size: uint) -> BigInt {
@@ -1287,7 +1279,7 @@ fn gen_bigint(&mut self, bit_size: uint) -> BigInt {
         } else {
             Minus
         };
-        return BigInt::from_biguint(sign, biguint);
+        BigInt::from_biguint(sign, biguint)
     }
 
     fn gen_biguint_below(&mut self, bound: &BigUint) -> BigUint {
@@ -1322,8 +1314,8 @@ impl BigInt {
     ///
     /// The digits are be in base 2^32.
     #[inline]
-    pub fn new(sign: Sign, v: Vec<BigDigit>) -> BigInt {
-        BigInt::from_biguint(sign, BigUint::new(v))
+    pub fn new(sign: Sign, digits: Vec<BigDigit>) -> BigInt {
+        BigInt::from_biguint(sign, BigUint::new(digits))
     }
 
     /// Creates and initializes a `BigInt`.
@@ -1334,7 +1326,7 @@ pub fn from_biguint(sign: Sign, data: BigUint) -> BigInt {
         if sign == Zero || data.is_zero() {
             return BigInt { sign: Zero, data: Zero::zero() };
         }
-        return BigInt { sign: sign, data: data };
+        BigInt { sign: sign, data: data }
     }
 
     /// Creates and initializes a `BigInt`.
@@ -1344,8 +1336,7 @@ pub fn from_slice(sign: Sign, slice: &[BigDigit]) -> BigInt {
     }
 
     /// Creates and initializes a `BigInt`.
-    pub fn parse_bytes(buf: &[u8], radix: uint)
-        -> Option<BigInt> {
+    pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<BigInt> {
         if buf.is_empty() { return None; }
         let mut sign  = Plus;
         let mut start = 0;
diff --git a/src/libnum/integer.rs b/src/libnum/integer.rs
new file mode 100644 (file)
index 0000000..d958d40
--- /dev/null
@@ -0,0 +1,411 @@
+// Copyright 2013-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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Integer trait and functions
+
+pub trait Integer: Num + PartialOrd
+                 + Div<Self, Self>
+                 + Rem<Self, Self> {
+    /// Simultaneous truncated integer division and modulus
+    #[inline]
+    fn div_rem(&self, other: &Self) -> (Self, Self) {
+        (*self / *other, *self % *other)
+    }
+
+    /// Floored integer division
+    ///
+    /// # Examples
+    ///
+    /// ~~~
+    /// # use num::Integer;
+    /// assert!(( 8i).div_floor(& 3) ==  2);
+    /// assert!(( 8i).div_floor(&-3) == -3);
+    /// assert!((-8i).div_floor(& 3) == -3);
+    /// assert!((-8i).div_floor(&-3) ==  2);
+    ///
+    /// assert!(( 1i).div_floor(& 2) ==  0);
+    /// assert!(( 1i).div_floor(&-2) == -1);
+    /// assert!((-1i).div_floor(& 2) == -1);
+    /// assert!((-1i).div_floor(&-2) ==  0);
+    /// ~~~
+    fn div_floor(&self, other: &Self) -> Self;
+
+    /// Floored integer modulo, satisfying:
+    ///
+    /// ~~~
+    /// # use num::Integer;
+    /// # let n = 1i; let d = 1i;
+    /// assert!(n.div_floor(&d) * d + n.mod_floor(&d) == n)
+    /// ~~~
+    ///
+    /// # Examples
+    ///
+    /// ~~~
+    /// # use num::Integer;
+    /// assert!(( 8i).mod_floor(& 3) ==  2);
+    /// assert!(( 8i).mod_floor(&-3) == -1);
+    /// assert!((-8i).mod_floor(& 3) ==  1);
+    /// assert!((-8i).mod_floor(&-3) == -2);
+    ///
+    /// assert!(( 1i).mod_floor(& 2) ==  1);
+    /// assert!(( 1i).mod_floor(&-2) == -1);
+    /// assert!((-1i).mod_floor(& 2) ==  1);
+    /// assert!((-1i).mod_floor(&-2) == -1);
+    /// ~~~
+    fn mod_floor(&self, other: &Self) -> Self;
+
+    /// Simultaneous floored integer division and modulus
+    fn div_mod_floor(&self, other: &Self) -> (Self, Self) {
+        (self.div_floor(other), self.mod_floor(other))
+    }
+
+    /// Greatest Common Divisor (GCD)
+    fn gcd(&self, other: &Self) -> Self;
+
+    /// Lowest Common Multiple (LCM)
+    fn lcm(&self, other: &Self) -> Self;
+
+    /// Returns `true` if `other` divides evenly into `self`
+    fn divides(&self, other: &Self) -> bool;
+
+    /// Returns `true` if the number is even
+    fn is_even(&self) -> bool;
+
+    /// Returns `true` if the number is odd
+    fn is_odd(&self) -> bool;
+}
+
+/// Simultaneous integer division and modulus
+#[inline] pub fn div_rem<T: Integer>(x: T, y: T) -> (T, T) { x.div_rem(&y) }
+/// Floored integer division
+#[inline] pub fn div_floor<T: Integer>(x: T, y: T) -> T { x.div_floor(&y) }
+/// Floored integer modulus
+#[inline] pub fn mod_floor<T: Integer>(x: T, y: T) -> T { x.mod_floor(&y) }
+/// Simultaneous floored integer division and modulus
+#[inline] pub fn div_mod_floor<T: Integer>(x: T, y: T) -> (T, T) { x.div_mod_floor(&y) }
+
+/// Calculates the Greatest Common Divisor (GCD) of the number and `other`. The
+/// result is always positive.
+#[inline(always)] pub fn gcd<T: Integer>(x: T, y: T) -> T { x.gcd(&y) }
+/// Calculates the Lowest Common Multiple (LCM) of the number and `other`.
+#[inline(always)] pub fn lcm<T: Integer>(x: T, y: T) -> T { x.lcm(&y) }
+
+macro_rules! impl_integer_for_int {
+    ($T:ty, $test_mod:ident) => (
+        impl Integer for $T {
+            /// Floored integer division
+            #[inline]
+            fn div_floor(&self, other: &$T) -> $T {
+                // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
+                // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
+                match self.div_rem(other) {
+                    (d, r) if (r > 0 && *other < 0)
+                           || (r < 0 && *other > 0) => d - 1,
+                    (d, _)                          => d,
+                }
+            }
+
+            /// Floored integer modulo
+            #[inline]
+            fn mod_floor(&self, other: &$T) -> $T {
+                // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
+                // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
+                match *self % *other {
+                    r if (r > 0 && *other < 0)
+                      || (r < 0 && *other > 0) => r + *other,
+                    r                          => r,
+                }
+            }
+
+            /// Calculates `div_floor` and `mod_floor` simultaneously
+            #[inline]
+            fn div_mod_floor(&self, other: &$T) -> ($T,$T) {
+                // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
+                // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
+                match self.div_rem(other) {
+                    (d, r) if (r > 0 && *other < 0)
+                           || (r < 0 && *other > 0) => (d - 1, r + *other),
+                    (d, r)                          => (d, r),
+                }
+            }
+
+            /// Calculates the Greatest Common Divisor (GCD) of the number and
+            /// `other`. The result is always positive.
+            #[inline]
+            fn gcd(&self, other: &$T) -> $T {
+                // Use Euclid's algorithm
+                let mut m = *self;
+                let mut n = *other;
+                while m != 0 {
+                    let temp = m;
+                    m = n % temp;
+                    n = temp;
+                }
+                n.abs()
+            }
+
+            /// Calculates the Lowest Common Multiple (LCM) of the number and
+            /// `other`.
+            #[inline]
+            fn lcm(&self, other: &$T) -> $T {
+                // should not have to recalculate abs
+                ((*self * *other) / self.gcd(other)).abs()
+            }
+
+            /// Returns `true` if the number can be divided by `other` without
+            /// leaving a remainder
+            #[inline]
+            fn divides(&self, other: &$T) -> bool { *self % *other == 0 }
+
+            /// Returns `true` if the number is divisible by `2`
+            #[inline]
+            fn is_even(&self) -> bool { self & 1 == 0 }
+
+            /// Returns `true` if the number is not divisible by `2`
+            #[inline]
+            fn is_odd(&self) -> bool { !self.is_even() }
+        }
+
+        #[cfg(test)]
+        mod $test_mod {
+            use Integer;
+
+            /// Checks that the division rule holds for:
+            ///
+            /// - `n`: numerator (dividend)
+            /// - `d`: denominator (divisor)
+            /// - `qr`: quotient and remainder
+            #[cfg(test)]
+            fn test_division_rule((n,d): ($T,$T), (q,r): ($T,$T)) {
+                assert_eq!(d * q + r, n);
+            }
+
+            #[test]
+            fn test_div_rem() {
+                fn test_nd_dr(nd: ($T,$T), qr: ($T,$T)) {
+                    let (n,d) = nd;
+                    let separate_div_rem = (n / d, n % d);
+                    let combined_div_rem = n.div_rem(&d);
+
+                    assert_eq!(separate_div_rem, qr);
+                    assert_eq!(combined_div_rem, qr);
+
+                    test_division_rule(nd, separate_div_rem);
+                    test_division_rule(nd, combined_div_rem);
+                }
+
+                test_nd_dr(( 8,  3), ( 2,  2));
+                test_nd_dr(( 8, -3), (-2,  2));
+                test_nd_dr((-8,  3), (-2, -2));
+                test_nd_dr((-8, -3), ( 2, -2));
+
+                test_nd_dr(( 1,  2), ( 0,  1));
+                test_nd_dr(( 1, -2), ( 0,  1));
+                test_nd_dr((-1,  2), ( 0, -1));
+                test_nd_dr((-1, -2), ( 0, -1));
+            }
+
+            #[test]
+            fn test_div_mod_floor() {
+                fn test_nd_dm(nd: ($T,$T), dm: ($T,$T)) {
+                    let (n,d) = nd;
+                    let separate_div_mod_floor = (n.div_floor(&d), n.mod_floor(&d));
+                    let combined_div_mod_floor = n.div_mod_floor(&d);
+
+                    assert_eq!(separate_div_mod_floor, dm);
+                    assert_eq!(combined_div_mod_floor, dm);
+
+                    test_division_rule(nd, separate_div_mod_floor);
+                    test_division_rule(nd, combined_div_mod_floor);
+                }
+
+                test_nd_dm(( 8,  3), ( 2,  2));
+                test_nd_dm(( 8, -3), (-3, -1));
+                test_nd_dm((-8,  3), (-3,  1));
+                test_nd_dm((-8, -3), ( 2, -2));
+
+                test_nd_dm(( 1,  2), ( 0,  1));
+                test_nd_dm(( 1, -2), (-1, -1));
+                test_nd_dm((-1,  2), (-1,  1));
+                test_nd_dm((-1, -2), ( 0, -1));
+            }
+
+            #[test]
+            fn test_gcd() {
+                assert_eq!((10 as $T).gcd(&2), 2 as $T);
+                assert_eq!((10 as $T).gcd(&3), 1 as $T);
+                assert_eq!((0 as $T).gcd(&3), 3 as $T);
+                assert_eq!((3 as $T).gcd(&3), 3 as $T);
+                assert_eq!((56 as $T).gcd(&42), 14 as $T);
+                assert_eq!((3 as $T).gcd(&-3), 3 as $T);
+                assert_eq!((-6 as $T).gcd(&3), 3 as $T);
+                assert_eq!((-4 as $T).gcd(&-2), 2 as $T);
+            }
+
+            #[test]
+            fn test_lcm() {
+                assert_eq!((1 as $T).lcm(&0), 0 as $T);
+                assert_eq!((0 as $T).lcm(&1), 0 as $T);
+                assert_eq!((1 as $T).lcm(&1), 1 as $T);
+                assert_eq!((-1 as $T).lcm(&1), 1 as $T);
+                assert_eq!((1 as $T).lcm(&-1), 1 as $T);
+                assert_eq!((-1 as $T).lcm(&-1), 1 as $T);
+                assert_eq!((8 as $T).lcm(&9), 72 as $T);
+                assert_eq!((11 as $T).lcm(&5), 55 as $T);
+            }
+
+            #[test]
+            fn test_even() {
+                assert_eq!((-4 as $T).is_even(), true);
+                assert_eq!((-3 as $T).is_even(), false);
+                assert_eq!((-2 as $T).is_even(), true);
+                assert_eq!((-1 as $T).is_even(), false);
+                assert_eq!((0 as $T).is_even(), true);
+                assert_eq!((1 as $T).is_even(), false);
+                assert_eq!((2 as $T).is_even(), true);
+                assert_eq!((3 as $T).is_even(), false);
+                assert_eq!((4 as $T).is_even(), true);
+            }
+
+            #[test]
+            fn test_odd() {
+                assert_eq!((-4 as $T).is_odd(), false);
+                assert_eq!((-3 as $T).is_odd(), true);
+                assert_eq!((-2 as $T).is_odd(), false);
+                assert_eq!((-1 as $T).is_odd(), true);
+                assert_eq!((0 as $T).is_odd(), false);
+                assert_eq!((1 as $T).is_odd(), true);
+                assert_eq!((2 as $T).is_odd(), false);
+                assert_eq!((3 as $T).is_odd(), true);
+                assert_eq!((4 as $T).is_odd(), false);
+            }
+        }
+    )
+}
+
+impl_integer_for_int!(i8,   test_integer_i8)
+impl_integer_for_int!(i16,  test_integer_i16)
+impl_integer_for_int!(i32,  test_integer_i32)
+impl_integer_for_int!(i64,  test_integer_i64)
+impl_integer_for_int!(int,  test_integer_int)
+
+macro_rules! impl_integer_for_uint {
+    ($T:ty, $test_mod:ident) => (
+        impl Integer for $T {
+            /// Unsigned integer division. Returns the same result as `div` (`/`).
+            #[inline]
+            fn div_floor(&self, other: &$T) -> $T { *self / *other }
+
+            /// Unsigned integer modulo operation. Returns the same result as `rem` (`%`).
+            #[inline]
+            fn mod_floor(&self, other: &$T) -> $T { *self % *other }
+
+            /// Calculates the Greatest Common Divisor (GCD) of the number and `other`
+            #[inline]
+            fn gcd(&self, other: &$T) -> $T {
+                // Use Euclid's algorithm
+                let mut m = *self;
+                let mut n = *other;
+                while m != 0 {
+                    let temp = m;
+                    m = n % temp;
+                    n = temp;
+                }
+                n
+            }
+
+            /// Calculates the Lowest Common Multiple (LCM) of the number and `other`
+            #[inline]
+            fn lcm(&self, other: &$T) -> $T {
+                (*self * *other) / self.gcd(other)
+            }
+
+            /// Returns `true` if the number can be divided by `other` without leaving a remainder
+            #[inline]
+            fn divides(&self, other: &$T) -> bool { *self % *other == 0 }
+
+            /// Returns `true` if the number is divisible by `2`
+            #[inline]
+            fn is_even(&self) -> bool { self & 1 == 0 }
+
+            /// Returns `true` if the number is not divisible by `2`
+            #[inline]
+            fn is_odd(&self) -> bool { !self.is_even() }
+        }
+
+        #[cfg(test)]
+        mod $test_mod {
+            use Integer;
+
+            #[test]
+            fn test_div_mod_floor() {
+                assert_eq!((10 as $T).div_floor(&(3 as $T)), 3 as $T);
+                assert_eq!((10 as $T).mod_floor(&(3 as $T)), 1 as $T);
+                assert_eq!((10 as $T).div_mod_floor(&(3 as $T)), (3 as $T, 1 as $T));
+                assert_eq!((5 as $T).div_floor(&(5 as $T)), 1 as $T);
+                assert_eq!((5 as $T).mod_floor(&(5 as $T)), 0 as $T);
+                assert_eq!((5 as $T).div_mod_floor(&(5 as $T)), (1 as $T, 0 as $T));
+                assert_eq!((3 as $T).div_floor(&(7 as $T)), 0 as $T);
+                assert_eq!((3 as $T).mod_floor(&(7 as $T)), 3 as $T);
+                assert_eq!((3 as $T).div_mod_floor(&(7 as $T)), (0 as $T, 3 as $T));
+            }
+
+            #[test]
+            fn test_gcd() {
+                assert_eq!((10 as $T).gcd(&2), 2 as $T);
+                assert_eq!((10 as $T).gcd(&3), 1 as $T);
+                assert_eq!((0 as $T).gcd(&3), 3 as $T);
+                assert_eq!((3 as $T).gcd(&3), 3 as $T);
+                assert_eq!((56 as $T).gcd(&42), 14 as $T);
+            }
+
+            #[test]
+            fn test_lcm() {
+                assert_eq!((1 as $T).lcm(&0), 0 as $T);
+                assert_eq!((0 as $T).lcm(&1), 0 as $T);
+                assert_eq!((1 as $T).lcm(&1), 1 as $T);
+                assert_eq!((8 as $T).lcm(&9), 72 as $T);
+                assert_eq!((11 as $T).lcm(&5), 55 as $T);
+                assert_eq!((99 as $T).lcm(&17), 1683 as $T);
+            }
+
+            #[test]
+            fn test_divides() {
+                assert!((6 as $T).divides(&(6 as $T)));
+                assert!((6 as $T).divides(&(3 as $T)));
+                assert!((6 as $T).divides(&(1 as $T)));
+            }
+
+            #[test]
+            fn test_even() {
+                assert_eq!((0 as $T).is_even(), true);
+                assert_eq!((1 as $T).is_even(), false);
+                assert_eq!((2 as $T).is_even(), true);
+                assert_eq!((3 as $T).is_even(), false);
+                assert_eq!((4 as $T).is_even(), true);
+            }
+
+            #[test]
+            fn test_odd() {
+                assert_eq!((0 as $T).is_odd(), false);
+                assert_eq!((1 as $T).is_odd(), true);
+                assert_eq!((2 as $T).is_odd(), false);
+                assert_eq!((3 as $T).is_odd(), true);
+                assert_eq!((4 as $T).is_odd(), false);
+            }
+        }
+    )
+}
+
+impl_integer_for_uint!(u8,   test_integer_u8)
+impl_integer_for_uint!(u16,  test_integer_u16)
+impl_integer_for_uint!(u32,  test_integer_u32)
+impl_integer_for_uint!(u64,  test_integer_u64)
+impl_integer_for_uint!(uint, test_integer_uint)
index fae21e80f307256101498420fc2459bc9109e80a..709882c87cedb970b3be3f693517592507fefd77 100644 (file)
 
 extern crate rand;
 
+pub use bigint::{BigInt, BigUint};
+pub use rational::{Rational, BigRational};
+pub use complex::Complex;
+pub use integer::Integer;
+
 pub mod bigint;
-pub mod rational;
 pub mod complex;
-
-pub trait Integer: Num + PartialOrd
-                 + Div<Self, Self>
-                 + Rem<Self, Self> {
-    /// Simultaneous truncated integer division and modulus
-    #[inline]
-    fn div_rem(&self, other: &Self) -> (Self, Self) {
-        (*self / *other, *self % *other)
-    }
-
-    /// Floored integer division
-    ///
-    /// # Examples
-    ///
-    /// ~~~
-    /// # use num::Integer;
-    /// assert!(( 8i).div_floor(& 3) ==  2);
-    /// assert!(( 8i).div_floor(&-3) == -3);
-    /// assert!((-8i).div_floor(& 3) == -3);
-    /// assert!((-8i).div_floor(&-3) ==  2);
-    ///
-    /// assert!(( 1i).div_floor(& 2) ==  0);
-    /// assert!(( 1i).div_floor(&-2) == -1);
-    /// assert!((-1i).div_floor(& 2) == -1);
-    /// assert!((-1i).div_floor(&-2) ==  0);
-    /// ~~~
-    fn div_floor(&self, other: &Self) -> Self;
-
-    /// Floored integer modulo, satisfying:
-    ///
-    /// ~~~
-    /// # use num::Integer;
-    /// # let n = 1i; let d = 1i;
-    /// assert!(n.div_floor(&d) * d + n.mod_floor(&d) == n)
-    /// ~~~
-    ///
-    /// # Examples
-    ///
-    /// ~~~
-    /// # use num::Integer;
-    /// assert!(( 8i).mod_floor(& 3) ==  2);
-    /// assert!(( 8i).mod_floor(&-3) == -1);
-    /// assert!((-8i).mod_floor(& 3) ==  1);
-    /// assert!((-8i).mod_floor(&-3) == -2);
-    ///
-    /// assert!(( 1i).mod_floor(& 2) ==  1);
-    /// assert!(( 1i).mod_floor(&-2) == -1);
-    /// assert!((-1i).mod_floor(& 2) ==  1);
-    /// assert!((-1i).mod_floor(&-2) == -1);
-    /// ~~~
-    fn mod_floor(&self, other: &Self) -> Self;
-
-    /// Simultaneous floored integer division and modulus
-    fn div_mod_floor(&self, other: &Self) -> (Self, Self) {
-        (self.div_floor(other), self.mod_floor(other))
-    }
-
-    /// Greatest Common Divisor (GCD)
-    fn gcd(&self, other: &Self) -> Self;
-
-    /// Lowest Common Multiple (LCM)
-    fn lcm(&self, other: &Self) -> Self;
-
-    /// Returns `true` if `other` divides evenly into `self`
-    fn divides(&self, other: &Self) -> bool;
-
-    /// Returns `true` if the number is even
-    fn is_even(&self) -> bool;
-
-    /// Returns `true` if the number is odd
-    fn is_odd(&self) -> bool;
-}
-
-/// Simultaneous integer division and modulus
-#[inline] pub fn div_rem<T: Integer>(x: T, y: T) -> (T, T) { x.div_rem(&y) }
-/// Floored integer division
-#[inline] pub fn div_floor<T: Integer>(x: T, y: T) -> T { x.div_floor(&y) }
-/// Floored integer modulus
-#[inline] pub fn mod_floor<T: Integer>(x: T, y: T) -> T { x.mod_floor(&y) }
-/// Simultaneous floored integer division and modulus
-#[inline] pub fn div_mod_floor<T: Integer>(x: T, y: T) -> (T, T) { x.div_mod_floor(&y) }
-
-/// Calculates the Greatest Common Divisor (GCD) of the number and `other`. The
-/// result is always positive.
-#[inline(always)] pub fn gcd<T: Integer>(x: T, y: T) -> T { x.gcd(&y) }
-/// Calculates the Lowest Common Multiple (LCM) of the number and `other`.
-#[inline(always)] pub fn lcm<T: Integer>(x: T, y: T) -> T { x.lcm(&y) }
-
-macro_rules! impl_integer_for_int {
-    ($T:ty, $test_mod:ident) => (
-        impl Integer for $T {
-            /// Floored integer division
-            #[inline]
-            fn div_floor(&self, other: &$T) -> $T {
-                // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
-                // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
-                match self.div_rem(other) {
-                    (d, r) if (r > 0 && *other < 0)
-                           || (r < 0 && *other > 0) => d - 1,
-                    (d, _)                          => d,
-                }
-            }
-
-            /// Floored integer modulo
-            #[inline]
-            fn mod_floor(&self, other: &$T) -> $T {
-                // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
-                // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
-                match *self % *other {
-                    r if (r > 0 && *other < 0)
-                      || (r < 0 && *other > 0) => r + *other,
-                    r                          => r,
-                }
-            }
-
-            /// Calculates `div_floor` and `mod_floor` simultaneously
-            #[inline]
-            fn div_mod_floor(&self, other: &$T) -> ($T,$T) {
-                // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
-                // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
-                match self.div_rem(other) {
-                    (d, r) if (r > 0 && *other < 0)
-                           || (r < 0 && *other > 0) => (d - 1, r + *other),
-                    (d, r)                          => (d, r),
-                }
-            }
-
-            /// Calculates the Greatest Common Divisor (GCD) of the number and
-            /// `other`. The result is always positive.
-            #[inline]
-            fn gcd(&self, other: &$T) -> $T {
-                // Use Euclid's algorithm
-                let mut m = *self;
-                let mut n = *other;
-                while m != 0 {
-                    let temp = m;
-                    m = n % temp;
-                    n = temp;
-                }
-                n.abs()
-            }
-
-            /// Calculates the Lowest Common Multiple (LCM) of the number and
-            /// `other`.
-            #[inline]
-            fn lcm(&self, other: &$T) -> $T {
-                // should not have to recalculate abs
-                ((*self * *other) / self.gcd(other)).abs()
-            }
-
-            /// Returns `true` if the number can be divided by `other` without
-            /// leaving a remainder
-            #[inline]
-            fn divides(&self, other: &$T) -> bool { *self % *other == 0 }
-
-            /// Returns `true` if the number is divisible by `2`
-            #[inline]
-            fn is_even(&self) -> bool { self & 1 == 0 }
-
-            /// Returns `true` if the number is not divisible by `2`
-            #[inline]
-            fn is_odd(&self) -> bool { !self.is_even() }
-        }
-
-        #[cfg(test)]
-        mod $test_mod {
-            use Integer;
-
-            /// Checks that the division rule holds for:
-            ///
-            /// - `n`: numerator (dividend)
-            /// - `d`: denominator (divisor)
-            /// - `qr`: quotient and remainder
-            #[cfg(test)]
-            fn test_division_rule((n,d): ($T,$T), (q,r): ($T,$T)) {
-                assert_eq!(d * q + r, n);
-            }
-
-            #[test]
-            fn test_div_rem() {
-                fn test_nd_dr(nd: ($T,$T), qr: ($T,$T)) {
-                    let (n,d) = nd;
-                    let separate_div_rem = (n / d, n % d);
-                    let combined_div_rem = n.div_rem(&d);
-
-                    assert_eq!(separate_div_rem, qr);
-                    assert_eq!(combined_div_rem, qr);
-
-                    test_division_rule(nd, separate_div_rem);
-                    test_division_rule(nd, combined_div_rem);
-                }
-
-                test_nd_dr(( 8,  3), ( 2,  2));
-                test_nd_dr(( 8, -3), (-2,  2));
-                test_nd_dr((-8,  3), (-2, -2));
-                test_nd_dr((-8, -3), ( 2, -2));
-
-                test_nd_dr(( 1,  2), ( 0,  1));
-                test_nd_dr(( 1, -2), ( 0,  1));
-                test_nd_dr((-1,  2), ( 0, -1));
-                test_nd_dr((-1, -2), ( 0, -1));
-            }
-
-            #[test]
-            fn test_div_mod_floor() {
-                fn test_nd_dm(nd: ($T,$T), dm: ($T,$T)) {
-                    let (n,d) = nd;
-                    let separate_div_mod_floor = (n.div_floor(&d), n.mod_floor(&d));
-                    let combined_div_mod_floor = n.div_mod_floor(&d);
-
-                    assert_eq!(separate_div_mod_floor, dm);
-                    assert_eq!(combined_div_mod_floor, dm);
-
-                    test_division_rule(nd, separate_div_mod_floor);
-                    test_division_rule(nd, combined_div_mod_floor);
-                }
-
-                test_nd_dm(( 8,  3), ( 2,  2));
-                test_nd_dm(( 8, -3), (-3, -1));
-                test_nd_dm((-8,  3), (-3,  1));
-                test_nd_dm((-8, -3), ( 2, -2));
-
-                test_nd_dm(( 1,  2), ( 0,  1));
-                test_nd_dm(( 1, -2), (-1, -1));
-                test_nd_dm((-1,  2), (-1,  1));
-                test_nd_dm((-1, -2), ( 0, -1));
-            }
-
-            #[test]
-            fn test_gcd() {
-                assert_eq!((10 as $T).gcd(&2), 2 as $T);
-                assert_eq!((10 as $T).gcd(&3), 1 as $T);
-                assert_eq!((0 as $T).gcd(&3), 3 as $T);
-                assert_eq!((3 as $T).gcd(&3), 3 as $T);
-                assert_eq!((56 as $T).gcd(&42), 14 as $T);
-                assert_eq!((3 as $T).gcd(&-3), 3 as $T);
-                assert_eq!((-6 as $T).gcd(&3), 3 as $T);
-                assert_eq!((-4 as $T).gcd(&-2), 2 as $T);
-            }
-
-            #[test]
-            fn test_lcm() {
-                assert_eq!((1 as $T).lcm(&0), 0 as $T);
-                assert_eq!((0 as $T).lcm(&1), 0 as $T);
-                assert_eq!((1 as $T).lcm(&1), 1 as $T);
-                assert_eq!((-1 as $T).lcm(&1), 1 as $T);
-                assert_eq!((1 as $T).lcm(&-1), 1 as $T);
-                assert_eq!((-1 as $T).lcm(&-1), 1 as $T);
-                assert_eq!((8 as $T).lcm(&9), 72 as $T);
-                assert_eq!((11 as $T).lcm(&5), 55 as $T);
-            }
-
-            #[test]
-            fn test_even() {
-                assert_eq!((-4 as $T).is_even(), true);
-                assert_eq!((-3 as $T).is_even(), false);
-                assert_eq!((-2 as $T).is_even(), true);
-                assert_eq!((-1 as $T).is_even(), false);
-                assert_eq!((0 as $T).is_even(), true);
-                assert_eq!((1 as $T).is_even(), false);
-                assert_eq!((2 as $T).is_even(), true);
-                assert_eq!((3 as $T).is_even(), false);
-                assert_eq!((4 as $T).is_even(), true);
-            }
-
-            #[test]
-            fn test_odd() {
-                assert_eq!((-4 as $T).is_odd(), false);
-                assert_eq!((-3 as $T).is_odd(), true);
-                assert_eq!((-2 as $T).is_odd(), false);
-                assert_eq!((-1 as $T).is_odd(), true);
-                assert_eq!((0 as $T).is_odd(), false);
-                assert_eq!((1 as $T).is_odd(), true);
-                assert_eq!((2 as $T).is_odd(), false);
-                assert_eq!((3 as $T).is_odd(), true);
-                assert_eq!((4 as $T).is_odd(), false);
-            }
-        }
-    )
-}
-
-impl_integer_for_int!(i8,   test_integer_i8)
-impl_integer_for_int!(i16,  test_integer_i16)
-impl_integer_for_int!(i32,  test_integer_i32)
-impl_integer_for_int!(i64,  test_integer_i64)
-impl_integer_for_int!(int,  test_integer_int)
-
-macro_rules! impl_integer_for_uint {
-    ($T:ty, $test_mod:ident) => (
-        impl Integer for $T {
-            /// Unsigned integer division. Returns the same result as `div` (`/`).
-            #[inline]
-            fn div_floor(&self, other: &$T) -> $T { *self / *other }
-
-            /// Unsigned integer modulo operation. Returns the same result as `rem` (`%`).
-            #[inline]
-            fn mod_floor(&self, other: &$T) -> $T { *self % *other }
-
-            /// Calculates the Greatest Common Divisor (GCD) of the number and `other`
-            #[inline]
-            fn gcd(&self, other: &$T) -> $T {
-                // Use Euclid's algorithm
-                let mut m = *self;
-                let mut n = *other;
-                while m != 0 {
-                    let temp = m;
-                    m = n % temp;
-                    n = temp;
-                }
-                n
-            }
-
-            /// Calculates the Lowest Common Multiple (LCM) of the number and `other`
-            #[inline]
-            fn lcm(&self, other: &$T) -> $T {
-                (*self * *other) / self.gcd(other)
-            }
-
-            /// Returns `true` if the number can be divided by `other` without leaving a remainder
-            #[inline]
-            fn divides(&self, other: &$T) -> bool { *self % *other == 0 }
-
-            /// Returns `true` if the number is divisible by `2`
-            #[inline]
-            fn is_even(&self) -> bool { self & 1 == 0 }
-
-            /// Returns `true` if the number is not divisible by `2`
-            #[inline]
-            fn is_odd(&self) -> bool { !self.is_even() }
-        }
-
-        #[cfg(test)]
-        mod $test_mod {
-            use Integer;
-
-            #[test]
-            fn test_div_mod_floor() {
-                assert_eq!((10 as $T).div_floor(&(3 as $T)), 3 as $T);
-                assert_eq!((10 as $T).mod_floor(&(3 as $T)), 1 as $T);
-                assert_eq!((10 as $T).div_mod_floor(&(3 as $T)), (3 as $T, 1 as $T));
-                assert_eq!((5 as $T).div_floor(&(5 as $T)), 1 as $T);
-                assert_eq!((5 as $T).mod_floor(&(5 as $T)), 0 as $T);
-                assert_eq!((5 as $T).div_mod_floor(&(5 as $T)), (1 as $T, 0 as $T));
-                assert_eq!((3 as $T).div_floor(&(7 as $T)), 0 as $T);
-                assert_eq!((3 as $T).mod_floor(&(7 as $T)), 3 as $T);
-                assert_eq!((3 as $T).div_mod_floor(&(7 as $T)), (0 as $T, 3 as $T));
-            }
-
-            #[test]
-            fn test_gcd() {
-                assert_eq!((10 as $T).gcd(&2), 2 as $T);
-                assert_eq!((10 as $T).gcd(&3), 1 as $T);
-                assert_eq!((0 as $T).gcd(&3), 3 as $T);
-                assert_eq!((3 as $T).gcd(&3), 3 as $T);
-                assert_eq!((56 as $T).gcd(&42), 14 as $T);
-            }
-
-            #[test]
-            fn test_lcm() {
-                assert_eq!((1 as $T).lcm(&0), 0 as $T);
-                assert_eq!((0 as $T).lcm(&1), 0 as $T);
-                assert_eq!((1 as $T).lcm(&1), 1 as $T);
-                assert_eq!((8 as $T).lcm(&9), 72 as $T);
-                assert_eq!((11 as $T).lcm(&5), 55 as $T);
-                assert_eq!((99 as $T).lcm(&17), 1683 as $T);
-            }
-
-            #[test]
-            fn test_divides() {
-                assert!((6 as $T).divides(&(6 as $T)));
-                assert!((6 as $T).divides(&(3 as $T)));
-                assert!((6 as $T).divides(&(1 as $T)));
-            }
-
-            #[test]
-            fn test_even() {
-                assert_eq!((0 as $T).is_even(), true);
-                assert_eq!((1 as $T).is_even(), false);
-                assert_eq!((2 as $T).is_even(), true);
-                assert_eq!((3 as $T).is_even(), false);
-                assert_eq!((4 as $T).is_even(), true);
-            }
-
-            #[test]
-            fn test_odd() {
-                assert_eq!((0 as $T).is_odd(), false);
-                assert_eq!((1 as $T).is_odd(), true);
-                assert_eq!((2 as $T).is_odd(), false);
-                assert_eq!((3 as $T).is_odd(), true);
-                assert_eq!((4 as $T).is_odd(), false);
-            }
-        }
-    )
-}
-
-impl_integer_for_uint!(u8,   test_integer_u8)
-impl_integer_for_uint!(u16,  test_integer_u16)
-impl_integer_for_uint!(u32,  test_integer_u32)
-impl_integer_for_uint!(u64,  test_integer_u64)
-impl_integer_for_uint!(uint, test_integer_uint)
+pub mod integer;
+pub mod rational;
index cfabf2b08e2e81ce574b8f44f5c0eefbdb3de328..b1a951498309fca3c1efed3dc8c1f6aa4c7a2f03 100644 (file)
@@ -81,7 +81,6 @@ struct GammaSmallShape {
 /// See `Gamma` for sampling from a Gamma distribution with general
 /// shape parameters.
 struct GammaLargeShape {
-    shape: f64,
     scale: f64,
     c: f64,
     d: f64
@@ -118,7 +117,6 @@ impl GammaLargeShape {
     fn new_raw(shape: f64, scale: f64) -> GammaLargeShape {
         let d = shape - 1. / 3.;
         GammaLargeShape {
-            shape: shape,
             scale: scale,
             c: 1. / (9. * d).sqrt(),
             d: d
index 91bbb23c337d0065764460f05231555d987ed620..ea472abeee690271b4ed6a12d582d81f633f81f9 100644 (file)
@@ -34,7 +34,7 @@ pub enum Inst {
 
     // The CharClass instruction tries to match one input character against
     // the range of characters given.
-    // The flags indicate whether to do a case insentivie match and whether
+    // The flags indicate whether to do a case insensitive match and whether
     // the character class is negated or not.
     CharClass(Vec<(char, char)>, Flags),
 
@@ -48,7 +48,7 @@ pub enum Inst {
     EmptyBegin(Flags),
 
     // Matches the end of the string, consumes no characters.
-    // The flags indicate whether it matches if the proceding character
+    // The flags indicate whether it matches if the proceeding character
     // is a new line.
     EmptyEnd(Flags),
 
index 04bc46e5dfc0dfe20cc7bb43774e2d19a8845cb0..59f53986af9fc8662cb1e25ed3942190d5408bd0 100644 (file)
@@ -189,7 +189,7 @@ fn describe_codegen_flags() {
     }
 }
 
-/// Process command line options. Emits messages as appropirate.If compilation
+/// Process command line options. Emits messages as appropriate. If compilation
 /// should continue, returns a getopts::Matches object parsed from args, otherwise
 /// returns None.
 pub fn handle_options(mut args: Vec<String>) -> Option<getopts::Matches> {
index a9b9892c2c9c33a514e3b40d818451fc084dc582..cd472321237624db94cc4ad4b6e4c6776dbb5145 100644 (file)
@@ -57,6 +57,7 @@
     ("linkage", Active),
     ("struct_inherit", Active),
     ("overloaded_calls", Active),
+    ("unboxed_closure_sugar", Active),
 
     ("quad_precision_float", Active),
 
@@ -291,6 +292,11 @@ fn visit_ty(&mut self, t: &ast::Ty, _: ()) {
 
             },
             ast::TyBox(_) => { self.gate_box(t.span); }
+            ast::TyUnboxedFn(_) => {
+                self.gate_feature("unboxed_closure_sugar",
+                                  t.span,
+                                  "unboxed closure trait sugar is experimental");
+            }
             _ => {}
         }
 
index 0514f7de505ef59b6baedfc161a0c171f0b3255a..0bb1481a4022572c6c0509e3201943af22e3568d 100644 (file)
@@ -130,9 +130,7 @@ fn inject_crates_ref(sess: &Session, krate: ast::Crate) -> ast::Crate {
     fold.fold_crate(krate)
 }
 
-struct PreludeInjector<'a> {
-    sess: &'a Session,
-}
+struct PreludeInjector<'a>;
 
 
 impl<'a> fold::Folder for PreludeInjector<'a> {
@@ -223,9 +221,7 @@ fn fold_mod(&mut self, module: &ast::Mod) -> ast::Mod {
     }
 }
 
-fn inject_prelude(sess: &Session, krate: ast::Crate) -> ast::Crate {
-    let mut fold = PreludeInjector {
-        sess: sess,
-    };
+fn inject_prelude(_: &Session, krate: ast::Crate) -> ast::Crate {
+    let mut fold = PreludeInjector;
     fold.fold_crate(krate)
 }
index c7ad74dce571c5fcae73c6900728d68fa3fe0fd0..0a88abd67d9dfffab5e5c96512b81598c23f745c 100644 (file)
@@ -321,3 +321,8 @@ pub fn get_reachable_extern_fns(cstore: &cstore::CStore, cnum: ast::CrateNum)
     let cdata = cstore.get_crate_data(cnum);
     decoder::get_reachable_extern_fns(&*cdata)
 }
+
+pub fn is_typedef(cstore: &cstore::CStore, did: ast::DefId) -> bool {
+    let cdata = cstore.get_crate_data(did.krate);
+    decoder::is_typedef(&*cdata, did.node)
+}
index 8a2c3c08d419ae8b1c319366173901758b1332d7..56d6766e1b719f6be681c7f2d0bdb7d820194c2f 100644 (file)
@@ -1339,3 +1339,11 @@ pub fn get_reachable_extern_fns(cdata: Cmd) -> Vec<ast::DefId> {
     });
     return ret;
 }
+
+pub fn is_typedef(cdata: Cmd, id: ast::NodeId) -> bool {
+    let item_doc = lookup_item(id, cdata.data());
+    match item_family(item_doc) {
+        Type => true,
+        _ => false,
+    }
+}
index 9033b83d47420cacf22e2d3c6088f5cc8efb9cd9..ec46e7f8592d3391ffbc4e69e101bf47df625e61 100644 (file)
@@ -13,7 +13,7 @@
 use std::cell::RefCell;
 use std::os;
 use std::io::fs;
-use std::unstable::dynamic_lib::DynamicLibrary;
+use std::dynamic_lib::DynamicLibrary;
 use std::collections::HashSet;
 
 use myfs = util::fs;
index acd96b94f315e3e4def4ba6fbf8cd7f25dc40f5e..cfda97ad26fd77860573621c224ec92743bd548d 100644 (file)
@@ -86,7 +86,7 @@ pub struct Library {
 }
 
 pub struct ArchiveMetadata {
-    archive: ArchiveRO,
+    _archive: ArchiveRO,
     // See comments in ArchiveMetadata::new for why this is static
     data: &'static [u8],
 }
@@ -487,7 +487,7 @@ fn new(ar: ArchiveRO) -> Option<ArchiveMetadata> {
             unsafe { mem::transmute(data) }
         };
         Some(ArchiveMetadata {
-            archive: ar,
+            _archive: ar,
             data: data,
         })
     }
index f48dbecc53025e362f0b5e2858ea979fa9284c1f..363fcf79eb52129384083a38d87d9310f15f0cff 100644 (file)
@@ -42,8 +42,6 @@ pub struct ctxt<'a> {
 // Extra parameters are for converting to/from def_ids in the string rep.
 // Whatever format you choose should not contain pipe characters.
 pub struct ty_abbrev {
-    pos: uint,
-    len: uint,
     s: String
 }
 
@@ -68,8 +66,6 @@ fn estimate_sz(u: u64) -> u64 {
     if abbrev_len < len {
         // I.e. it's actually an abbreviation.
         cx.abbrevs.borrow_mut().insert(t, ty_abbrev {
-            pos: pos as uint,
-            len: len as uint,
             s: format!("\\#{:x}:{:x}\\#", pos, len)
         });
     }
index 74faf7cf17c0c47061f4e958d59fd986fe0e0641..2427df463bfe438751a5f9e904fc6a1e5ac35c02 100644 (file)
@@ -551,7 +551,7 @@ struct defined in `middle::borrowck`. Formally, we define `LOAN` as
 The reasoning here is that a mutable borrow must be the only writer,
 therefore it prevents other writes (`MUTATE`), mutable borrows
 (`CLAIM`), and immutable borrows (`FREEZE`). An immutable borrow
-permits other immutable borrows but forbids writes and mutable borows.
+permits other immutable borrows but forbids writes and mutable borrows.
 Finally, a const borrow just wants to be sure that the value is not
 moved out from under it, so no actions are forbidden.
 
index 3337a56edf008d8f52f7e29d1f6d03bb3a034c43..dc8567af9edad9fb9727a8639815791ca6d86479 100644 (file)
@@ -29,7 +29,7 @@ pub fn guarantee_lifetime(bccx: &BorrowckCtxt,
                           cause: euv::LoanCause,
                           cmt: mc::cmt,
                           loan_region: ty::Region,
-                          loan_kind: ty::BorrowKind)
+                          _: ty::BorrowKind)
                           -> Result<(),()> {
     debug!("guarantee_lifetime(cmt={}, loan_region={})",
            cmt.repr(bccx.tcx), loan_region.repr(bccx.tcx));
@@ -38,7 +38,6 @@ pub fn guarantee_lifetime(bccx: &BorrowckCtxt,
                                          span: span,
                                          cause: cause,
                                          loan_region: loan_region,
-                                         loan_kind: loan_kind,
                                          cmt_original: cmt.clone()};
     ctxt.check(&cmt, None)
 }
@@ -55,7 +54,6 @@ struct GuaranteeLifetimeContext<'a> {
     span: Span,
     cause: euv::LoanCause,
     loan_region: ty::Region,
-    loan_kind: ty::BorrowKind,
     cmt_original: mc::cmt
 }
 
index 003687e7b63f9e342c86074d2fd4e3c9fa346a2d..ec362f924418c0ba77b8ea153a0ece57efbafdbb 100644 (file)
@@ -310,7 +310,6 @@ fn guarantee_valid(&mut self,
                 Loan {
                     index: self.all_loans.len(),
                     loan_path: loan_path,
-                    cmt: cmt,
                     kind: req_kind,
                     gen_scope: gen_scope,
                     kill_scope: kill_scope,
@@ -481,8 +480,7 @@ pub fn report_potential_errors(&self) {
 /// This visitor walks static initializer's expressions and makes
 /// sure the loans being taken are sound.
 struct StaticInitializerCtxt<'a> {
-    bccx: &'a BorrowckCtxt<'a>,
-    item_ub: ast::NodeId,
+    bccx: &'a BorrowckCtxt<'a>
 }
 
 impl<'a> visit::Visitor<()> for StaticInitializerCtxt<'a> {
@@ -509,8 +507,7 @@ pub fn gather_loans_in_static_initializer(bccx: &mut BorrowckCtxt, expr: &ast::E
     debug!("gather_loans_in_static_initializer(expr={})", expr.repr(bccx.tcx));
 
     let mut sicx = StaticInitializerCtxt {
-        bccx: bccx,
-        item_ub: expr.id,
+        bccx: bccx
     };
 
     sicx.visit_expr(expr, ());
index 552381e4216538bd7d6bb7078a3f0bc2a9fceffd..7c1f5937472970f86af8903950c8a46b1fa13063 100644 (file)
@@ -36,7 +36,6 @@ pub fn compute_restrictions(bccx: &BorrowckCtxt,
         bccx: bccx,
         span: span,
         cause: cause,
-        cmt_original: cmt.clone(),
         loan_region: loan_region,
     };
 
@@ -49,7 +48,6 @@ pub fn compute_restrictions(bccx: &BorrowckCtxt,
 struct RestrictionsContext<'a> {
     bccx: &'a BorrowckCtxt<'a>,
     span: Span,
-    cmt_original: mc::cmt,
     loan_region: ty::Region,
     cause: euv::LoanCause,
 }
index 5706d249c46dabd98f12e670462b468dff96c1f1..7aaba22dd843584150e5e50bbdd2ea8379bb7a1e 100644 (file)
@@ -180,7 +180,6 @@ pub enum PartialTotal {
 pub struct Loan {
     index: uint,
     loan_path: Rc<LoanPath>,
-    cmt: mc::cmt,
     kind: ty::BorrowKind,
     restrictions: Vec<Restriction>,
     gen_scope: ast::NodeId,
index fb19fbd70c69e117c0159c6454bbc6bcc956b179..46899ae19ca095f84bed03c2c85fe211cca8f2de 100644 (file)
@@ -124,6 +124,32 @@ fn lookup_and_handle_method(&mut self, id: ast::NodeId,
         }
     }
 
+    fn handle_field_access(&mut self, lhs: &ast::Expr, name: &ast::Ident) {
+        match ty::get(ty::expr_ty_adjusted(self.tcx, lhs)).sty {
+            ty::ty_struct(id, _) => {
+                let fields = ty::lookup_struct_fields(self.tcx, id);
+                let field_id = fields.iter()
+                    .find(|field| field.name == name.name).unwrap().id;
+                self.live_symbols.insert(field_id.node);
+            },
+            _ => ()
+        }
+    }
+
+    fn handle_field_pattern_match(&mut self, lhs: &ast::Pat, pats: &[ast::FieldPat]) {
+        match self.tcx.def_map.borrow().get(&lhs.id) {
+            &def::DefStruct(id) | &def::DefVariant(_, id, _) => {
+                let fields = ty::lookup_struct_fields(self.tcx, id);
+                for pat in pats.iter() {
+                    let field_id = fields.iter()
+                        .find(|field| field.name == pat.ident.name).unwrap().id;
+                    self.live_symbols.insert(field_id.node);
+                }
+            }
+            _ => ()
+        }
+    }
+
     fn mark_live_symbols(&mut self) {
         let mut scanned = HashSet::new();
         while self.worklist.len() > 0 {
@@ -147,10 +173,22 @@ fn visit_node(&mut self, node: &ast_map::Node) {
         match *node {
             ast_map::NodeItem(item) => {
                 match item.node {
+                    ast::ItemStruct(struct_def, _) => {
+                        let has_extern_repr = item.attrs.iter().fold(attr::ReprAny, |acc, attr| {
+                            attr::find_repr_attr(self.tcx.sess.diagnostic(), attr, acc)
+                        }) == attr::ReprExtern;
+                        let live_fields = struct_def.fields.iter().filter(|f| {
+                            has_extern_repr || match f.node.kind {
+                                ast::NamedField(_, ast::Public) => true,
+                                _ => false
+                            }
+                        });
+                        self.live_symbols.extend(live_fields.map(|f| f.node.id));
+                        visit::walk_item(self, item, ());
+                    }
                     ast::ItemFn(..)
                     | ast::ItemTy(..)
                     | ast::ItemEnum(..)
-                    | ast::ItemStruct(..)
                     | ast::ItemStatic(..) => {
                         visit::walk_item(self, item, ());
                     }
@@ -178,18 +216,32 @@ fn visit_expr(&mut self, expr: &ast::Expr, _: ()) {
             ast::ExprMethodCall(..) => {
                 self.lookup_and_handle_method(expr.id, expr.span);
             }
+            ast::ExprField(ref lhs, ref ident, _) => {
+                self.handle_field_access(*lhs, ident);
+            }
             _ => ()
         }
 
         visit::walk_expr(self, expr, ())
     }
 
+    fn visit_pat(&mut self, pat: &ast::Pat, _: ()) {
+        match pat.node {
+            ast::PatStruct(_, ref fields, _) => {
+                self.handle_field_pattern_match(pat, fields.as_slice());
+            }
+            _ => ()
+        }
+
+        visit::walk_pat(self, pat, ())
+    }
+
     fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId, _: ()) {
         self.lookup_and_handle_definition(&id);
         visit::walk_path(self, path, ());
     }
 
-    fn visit_item(&mut self, _item: &ast::Item, _: ()) {
+    fn visit_item(&mut self, _: &ast::Item, _: ()) {
         // Do not recurse into items. These items will be added to the
         // worklist and recursed into manually if necessary.
     }
@@ -317,6 +369,23 @@ struct DeadVisitor<'a> {
 }
 
 impl<'a> DeadVisitor<'a> {
+    fn should_warn_about_field(&mut self, node: &ast::StructField_) -> bool {
+        let (is_named, has_leading_underscore) = match node.ident() {
+            Some(ref ident) => (true, token::get_ident(*ident).get()[0] == ('_' as u8)),
+            _ => (false, false)
+        };
+        let field_type = ty::node_id_to_type(self.tcx, node.id);
+        let is_marker_field = match ty::ty_to_def_id(field_type) {
+            Some(def_id) => self.tcx.lang_items.items().any(|(_, item)| *item == Some(def_id)),
+            _ => false
+        };
+        is_named
+            && !self.symbol_is_live(node.id, None)
+            && !has_leading_underscore
+            && !is_marker_field
+            && !has_allow_dead_code_or_lang_attr(node.attrs.as_slice())
+    }
+
     // id := node id of an item's definition.
     // ctor_id := `Some` if the item is a struct_ctor (tuple struct),
     //            `None` otherwise.
@@ -399,6 +468,14 @@ fn visit_fn(&mut self, fk: &visit::FnKind,
         visit::walk_block(self, block, ());
     }
 
+    fn visit_struct_field(&mut self, field: &ast::StructField, _: ()) {
+        if self.should_warn_about_field(&field.node) {
+            self.warn_dead_code(field.node.id, field.span, field.node.ident().unwrap());
+        }
+
+        visit::walk_struct_field(self, field, ());
+    }
+
     // Overwrite so that we don't warn the trait method itself.
     fn visit_trait_method(&mut self, trait_method: &ast::TraitMethod, _: ()) {
         match *trait_method {
index 540dfdab19e990b6362f1926bf4e6e07954ae41f..dbf8a1b0be8a3a5dea87117f9a0035006e7f3b8d 100644 (file)
@@ -438,7 +438,7 @@ fn walk_callee(&mut self, call: &ast::Expr, callee: &ast::Expr) {
                     None => {
                         self.tcx().sess.span_bug(
                             callee.span,
-                            format!("unxpected callee type {}",
+                            format!("unexpected callee type {}",
                                     callee_ty.repr(self.tcx())).as_slice());
                     }
                 }
index cd6010127084b42e739fbe1b6c2ddeb0298209d2..e3a89fe2525d2a8ed4587f6e3b7bd9f416499d66 100644 (file)
@@ -257,7 +257,7 @@ pub fn each_adjacent_edge<'a>(&'a self,
     //
     // A common use for graphs in our compiler is to perform
     // fixed-point iteration. In this case, each edge represents a
-    // constaint, and the nodes themselves are associated with
+    // constraint, and the nodes themselves are associated with
     // variables or other bitsets. This method facilitates such a
     // computation.
 
index 278d5d8187b72440c3dd6c4482737fc81db8a6d9..a7fd81e9c9a83e84f2368831d9107fddf06392a2 100644 (file)
@@ -226,21 +226,12 @@ fn invalid_node() -> LiveNode { LiveNode(uint::MAX) }
 
 struct CaptureInfo {
     ln: LiveNode,
-    is_move: bool,
     var_nid: NodeId
 }
 
-enum LocalKind {
-    FromMatch(BindingMode),
-    FromLetWithInitializer,
-    FromLetNoInitializer
-}
-
 struct LocalInfo {
     id: NodeId,
-    ident: Ident,
-    is_mutbl: bool,
-    kind: LocalKind,
+    ident: Ident
 }
 
 enum VarKind {
@@ -406,23 +397,13 @@ fn visit_fn(ir: &mut IrMaps,
 }
 
 fn visit_local(ir: &mut IrMaps, local: &Local) {
-    pat_util::pat_bindings(&ir.tcx.def_map, local.pat, |bm, p_id, sp, path| {
+    pat_util::pat_bindings(&ir.tcx.def_map, local.pat, |_, p_id, sp, path| {
         debug!("adding local variable {}", p_id);
         let name = ast_util::path_to_ident(path);
         ir.add_live_node_for_node(p_id, VarDefNode(sp));
-        let kind = match local.init {
-          Some(_) => FromLetWithInitializer,
-          None => FromLetNoInitializer
-        };
-        let mutbl = match bm {
-            BindByValue(MutMutable) => true,
-            _ => false
-        };
         ir.add_variable(Local(LocalInfo {
           id: p_id,
-          ident: name,
-          is_mutbl: mutbl,
-          kind: kind
+          ident: name
         }));
     });
     visit::walk_local(ir, local, ());
@@ -434,16 +415,10 @@ fn visit_arm(ir: &mut IrMaps, arm: &Arm) {
             debug!("adding local variable {} from match with bm {:?}",
                    p_id, bm);
             let name = ast_util::path_to_ident(path);
-            let mutbl = match bm {
-                BindByValue(MutMutable) => true,
-                _ => false
-            };
             ir.add_live_node_for_node(p_id, VarDefNode(sp));
             ir.add_variable(Local(LocalInfo {
                 id: p_id,
-                ident: name,
-                is_mutbl: mutbl,
-                kind: FromMatch(bm)
+                ident: name
             }));
         })
     }
@@ -481,27 +456,12 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
         // in better error messages than just pointing at the closure
         // construction site.
         let mut call_caps = Vec::new();
-        let fv_mode = freevars::get_capture_mode(ir.tcx, expr.id);
         freevars::with_freevars(ir.tcx, expr.id, |freevars| {
             for fv in freevars.iter() {
                 match moved_variable_node_id_from_def(fv.def) {
                     Some(rv) => {
                         let fv_ln = ir.add_live_node(FreeVarNode(fv.span));
-                        let fv_id = fv.def.def_id().node;
-                        let fv_ty = ty::node_id_to_type(ir.tcx, fv_id);
-                        let is_move = match fv_mode {
-                            // var must be dead afterwards
-                            freevars::CaptureByValue => {
-                                ty::type_moves_by_default(ir.tcx, fv_ty)
-                            }
-
-                            // var can still be used
-                            freevars::CaptureByRef => {
-                                false
-                            }
-                        };
                         call_caps.push(CaptureInfo {ln: fv_ln,
-                                                    is_move: is_move,
                                                     var_nid: rv});
                     }
                     None => {}
index 06e0a12577270b359dc87e012d29db6ddeca3474..27a0f0022fd1ca82d22397c5ebaac075796963b1 100644 (file)
@@ -31,7 +31,7 @@
  * is the address of the lvalue.  If Expr is an rvalue, this is the address of
  * some temporary spot in memory where the result is stored.
  *
- * Now, cat_expr() classies the expression Expr and the address A=ToAddr(Expr)
+ * Now, cat_expr() classifies the expression Expr and the address A=ToAddr(Expr)
  * as follows:
  *
  * - cat: what kind of expression was this?  This is a subset of the
@@ -42,7 +42,7 @@
  *
  * The resulting categorization tree differs somewhat from the expressions
  * themselves.  For example, auto-derefs are explicit.  Also, an index a[b] is
- * decomposed into two operations: a derefence to reach the array data and
+ * decomposed into two operations: a dereference to reach the array data and
  * then an index to jump forward to the relevant item.
  *
  * ## By-reference upvars
index fcd6d4246592ba54bba18f4cadcaa4047252a363..50cbf6bbaf0c58abd0933c6baaabf411f9f51414 100644 (file)
@@ -353,7 +353,6 @@ fn visit_mod(&mut self, m: &ast::Mod, _sp: Span, id: ast::NodeId, _: ()) {
 struct PrivacyVisitor<'a> {
     tcx: &'a ty::ctxt,
     curitem: ast::NodeId,
-    in_fn: bool,
     in_foreign: bool,
     parents: NodeMap<ast::NodeId>,
     external_exports: resolve::ExternalExports,
@@ -1445,7 +1444,6 @@ pub fn check_crate(tcx: &ty::ctxt,
     // Use the parent map to check the privacy of everything
     let mut visitor = PrivacyVisitor {
         curitem: ast::DUMMY_NODE_ID,
-        in_fn: false,
         in_foreign: false,
         tcx: tcx,
         parents: visitor.parents,
index e22462efaa44a82a3e481dd1dacb6212d668c9b0..e2974615423eb6153e718403f37703934733b201 100644 (file)
@@ -39,7 +39,7 @@
 
 - `scope_map` maps from a scope id to the enclosing scope id; this is
   usually corresponding to the lexical nesting, though in the case of
-  closures the parent scope is the innermost conditinal expression or repeating
+  closures the parent scope is the innermost conditional expression or repeating
   block
 
 - `var_map` maps from a variable or binding id to the block in which
index 9bfa0e10aedeff3ba653d0e483356b144c51c8eb..b0a322a9eb7ed51c4ac7b1388b61dda36b1677c1 100644 (file)
@@ -806,7 +806,6 @@ fn namespace_error_to_str(ns: NamespaceError) -> &'static str {
 /// The main resolver class.
 struct Resolver<'a> {
     session: &'a Session,
-    lang_items: &'a LanguageItems,
 
     graph_root: NameBindings,
 
@@ -843,9 +842,6 @@ struct Resolver<'a> {
     // The idents for the primitive types.
     primitive_type_table: PrimitiveTypeTable,
 
-    // The four namespaces.
-    namespaces: Vec<Namespace> ,
-
     def_map: DefMap,
     export_map2: ExportMap2,
     trait_map: TraitMap,
@@ -902,7 +898,7 @@ fn visit_view_item(&mut self, vi: &ViewItem, _: ()) {
 }
 
 impl<'a> Resolver<'a> {
-    fn new(session: &'a Session, lang_items: &'a LanguageItems, crate_span: Span) -> Resolver<'a> {
+    fn new(session: &'a Session, crate_span: Span) -> Resolver<'a> {
         let graph_root = NameBindings::new();
 
         graph_root.define_module(NoParentLink,
@@ -916,7 +912,6 @@ fn new(session: &'a Session, lang_items: &'a LanguageItems, crate_span: Span) ->
 
         Resolver {
             session: session,
-            lang_items: lang_items,
 
             // The outermost module has def ID 0; this is not reflected in the
             // AST.
@@ -941,8 +936,6 @@ fn new(session: &'a Session, lang_items: &'a LanguageItems, crate_span: Span) ->
 
             primitive_type_table: PrimitiveTypeTable::new(),
 
-            namespaces: vec!(TypeNS, ValueNS),
-
             def_map: RefCell::new(NodeMap::new()),
             export_map2: RefCell::new(NodeMap::new()),
             trait_map: NodeMap::new(),
@@ -3856,14 +3849,20 @@ fn resolve_type_parameters(&mut self,
     }
 
     fn resolve_type_parameter_bound(&mut self,
-                                        id: NodeId,
-                                        type_parameter_bound: &TyParamBound) {
+                                    id: NodeId,
+                                    type_parameter_bound: &TyParamBound) {
         match *type_parameter_bound {
             TraitTyParamBound(ref tref) => {
                 self.resolve_trait_reference(id, tref, TraitBoundingTypeParameter)
             }
-            StaticRegionTyParamBound => {}
-            OtherRegionTyParamBound(_) => {}
+            UnboxedFnTyParamBound(ref unboxed_function) => {
+                for argument in unboxed_function.decl.inputs.iter() {
+                    self.resolve_type(argument.ty);
+                }
+
+                self.resolve_type(unboxed_function.decl.output);
+            }
+            StaticRegionTyParamBound | OtherRegionTyParamBound(_) => {}
         }
     }
 
@@ -5576,10 +5575,10 @@ pub struct CrateMap {
 
 /// Entry point to crate resolution.
 pub fn resolve_crate(session: &Session,
-                     lang_items: &LanguageItems,
+                     _: &LanguageItems,
                      krate: &Crate)
                   -> CrateMap {
-    let mut resolver = Resolver::new(session, lang_items, krate.span);
+    let mut resolver = Resolver::new(session, krate.span);
     resolver.resolve(krate);
     let Resolver { def_map, export_map2, trait_map, last_private,
                    external_exports, .. } = resolver;
index 2a3ec63e995ef3b089211fe9313339ca81acbc07..f6fb6c8ba2013e6c4f0dacdab5c96d6c009ce500 100644 (file)
@@ -312,9 +312,12 @@ fn trans_opt<'a>(bcx: &'a Block<'a>, o: &Opt) -> opt_result<'a> {
             let datum = datum::rvalue_scratch_datum(bcx, struct_ty, "");
             return single_result(Result::new(bcx, datum.val));
         }
-        lit(ConstLit(lit_id)) => {
-            let (llval, _) = consts::get_const_val(bcx.ccx(), lit_id);
-            return single_result(Result::new(bcx, llval));
+        lit(l @ ConstLit(ref def_id)) => {
+            let lit_ty = ty::node_id_to_type(bcx.tcx(), lit_to_expr(bcx.tcx(), &l).id);
+            let (llval, _) = consts::get_const_val(bcx.ccx(), *def_id);
+            let lit_datum = immediate_rvalue(llval, lit_ty);
+            let lit_datum = unpack_datum!(bcx, lit_datum.to_appropriate_datum(bcx));
+            return single_result(Result::new(bcx, lit_datum.val));
         }
         var(disr_val, ref repr) => {
             return adt::trans_case(bcx, &**repr, disr_val);
index 9fe403159f2b7ec3ac23bb86e262b68d194b0102..1b530ea34249193b3018b9e2dc66c8837295f267 100644 (file)
@@ -717,7 +717,7 @@ pub fn trans_field_ptr(bcx: &Block, r: &Repr, val: ValueRef, discr: Disr,
             let ty = type_of::type_of(bcx.ccx(), *nullfields.get(ix));
             assert_eq!(machine::llsize_of_alloc(bcx.ccx(), ty), 0);
             // The contents of memory at this pointer can't matter, but use
-            // the value that's "reasonable" in case of pointer comparision.
+            // the value that's "reasonable" in case of pointer comparison.
             PointerCast(bcx, val, ty.ptr_to())
         }
         RawNullablePointer { nndiscr, nnty, .. } => {
index 09f5d2a350769b79bf82024591c588ae200b7989..fc2e87f72bb49387faf3b38c95f6f024c6613afd 100644 (file)
@@ -106,7 +106,9 @@ pub fn init_insn_ctxt() {
     task_local_insn_key.replace(Some(RefCell::new(Vec::new())));
 }
 
-pub struct _InsnCtxt { _x: () }
+pub struct _InsnCtxt {
+    _cannot_construct_outside_of_this_module: ()
+}
 
 #[unsafe_destructor]
 impl Drop for _InsnCtxt {
@@ -124,7 +126,7 @@ pub fn push_ctxt(s: &'static str) -> _InsnCtxt {
         Some(ctx) => ctx.borrow_mut().push(s),
         None => {}
     }
-    _InsnCtxt { _x: () }
+    _InsnCtxt { _cannot_construct_outside_of_this_module: () }
 }
 
 pub struct StatRecorder<'a> {
@@ -1571,7 +1573,7 @@ fn enum_variant_size_lint(ccx: &CrateContext, enum_def: &ast::EnumDef, sp: Span,
                 for var in variants.iter() {
                     let mut size = 0;
                     for field in var.fields.iter().skip(1) {
-                        // skip the dicriminant
+                        // skip the discriminant
                         size += llsize_of_real(ccx, sizing_type_of(ccx, *field));
                     }
                     sizes.push(size);
@@ -2318,7 +2320,7 @@ pub fn trans_crate(krate: ast::Crate,
     // LLVM code generator emits a ".file filename" directive
     // for ELF backends. Value of the "filename" is set as the
     // LLVM module identifier.  Due to a LLVM MC bug[1], LLVM
-    // crashes if the module identifer is same as other symbols
+    // crashes if the module identifier is same as other symbols
     // such as a function name in the module.
     // 1. http://llvm.org/bugs/show_bug.cgi?id=11479
     let mut llmod_id = link_meta.crateid.name.clone();
index 1bcf47531dd561bb757da7e95b834f7e75e3ce24..9bd6b8ed3618c97b57397d274a6212b0af441960 100644 (file)
@@ -599,7 +599,7 @@ pub fn C_str_slice(cx: &CrateContext, s: InternedString) -> ValueRef {
         let len = s.get().len();
         let cs = llvm::LLVMConstPointerCast(C_cstr(cx, s, false),
                                             Type::i8p(cx).to_ref());
-        C_struct(cx, [cs, C_uint(cx, len)], false)
+        C_named_struct(cx.tn.find_type("str_slice").unwrap(), [cs, C_uint(cx, len)])
     }
 }
 
index 8607d52b6241fa8f9acbc0e05b915d148a1c3ccf..a80ae9e2596da0c16a2f0c2ad488f2a215dfb43e 100644 (file)
@@ -233,12 +233,12 @@ pub fn new(name: &str,
             ccx.int_type = Type::int(&ccx);
             ccx.opaque_vec_type = Type::opaque_vec(&ccx);
 
-            ccx.tn.associate_type("tydesc", &Type::tydesc(&ccx));
-
             let mut str_slice_ty = Type::named_struct(&ccx, "str_slice");
             str_slice_ty.set_struct_body([Type::i8p(&ccx), ccx.int_type], false);
             ccx.tn.associate_type("str_slice", &str_slice_ty);
 
+            ccx.tn.associate_type("tydesc", &Type::tydesc(&ccx, str_slice_ty));
+
             if ccx.sess().count_llvm_insns() {
                 base::init_insn_ctxt()
             }
index ea152c348087c4052d05682e862909f16f775464..a6290a8edb4421f33ab0b3419e22296889c966d8 100644 (file)
@@ -20,7 +20,6 @@
 use middle::trans::common::*;
 use middle::trans::debuginfo;
 use middle::trans::expr;
-use middle::trans::type_of;
 use middle::ty;
 use util::ppaux::Repr;
 
@@ -343,14 +342,10 @@ pub fn trans_ret<'a>(bcx: &'a Block<'a>,
 
 fn str_slice_arg<'a>(bcx: &'a Block<'a>, s: InternedString) -> ValueRef {
     let ccx = bcx.ccx();
-    let t = ty::mk_str_slice(bcx.tcx(), ty::ReStatic, ast::MutImmutable);
     let s = C_str_slice(ccx, s);
     let slot = alloca(bcx, val_ty(s), "__temp");
     Store(bcx, s, slot);
-
-    // The type of C_str_slice is { i8*, i64 }, but the type of the &str is
-    // %str_slice, so we do a bitcast here to the right type.
-    BitCast(bcx, slot, type_of::type_of(ccx, t).ptr_to())
+    slot
 }
 
 pub fn trans_fail<'a>(
index b709fa52cf730261906458ebc108e6cdec91ac27..df2f03a58411dce447b7b19420f5963acae2b760 100644 (file)
@@ -1527,7 +1527,7 @@ fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription
                 // As far as debuginfo is concerned, the pointer this enum represents is still
                 // wrapped in a struct. This is to make the DWARF representation of enums uniform.
 
-                // First create a description of the artifical wrapper struct:
+                // First create a description of the artificial wrapper struct:
                 let non_null_variant = self.variants.get(non_null_variant_index as uint);
                 let non_null_variant_ident = non_null_variant.name;
                 let non_null_variant_name = token::get_ident(non_null_variant_ident);
index 6f217d83a624a2497f29fd016d6940877c63d5a5..565fa88bf438e77cb0fdd2b0176b04d4a961eb48 100644 (file)
@@ -64,9 +64,6 @@ struct LlvmSignature {
     // function, because the foreign function may opt to return via an
     // out pointer.
     llret_ty: Type,
-
-    // True if *Rust* would use an outpointer for this function.
-    sret: bool,
 }
 
 
@@ -847,8 +844,7 @@ fn foreign_signature(ccx: &CrateContext, fn_sig: &ty::FnSig, arg_tys: &[ty::t])
     let llret_ty = type_of::type_of(ccx, fn_sig.output);
     LlvmSignature {
         llarg_tys: llarg_tys,
-        llret_ty: llret_ty,
-        sret: type_of::return_uses_outptr(ccx, fn_sig.output),
+        llret_ty: llret_ty
     }
 }
 
index dfe06f9ca4c89a9b87bac7fde066c03b127e1827..5d58500f761a4581044d0af023814b4c5a4391ee 100644 (file)
@@ -186,7 +186,7 @@ pub fn glue_fn(ccx: &CrateContext, t: Type) -> Type {
         Type::func([t], &Type::void(ccx))
     }
 
-    pub fn tydesc(ccx: &CrateContext) -> Type {
+    pub fn tydesc(ccx: &CrateContext, str_slice_ty: Type) -> Type {
         let mut tydesc = Type::named_struct(ccx, "tydesc");
         let glue_fn_ty = Type::glue_fn(ccx, Type::i8p(ccx)).ptr_to();
 
@@ -200,7 +200,7 @@ pub fn tydesc(ccx: &CrateContext) -> Type {
                      int_ty,     // align
                      glue_fn_ty, // drop
                      glue_fn_ty, // visit
-                     Type::struct_(ccx, [Type::i8p(ccx), Type::int(ccx)], false)]; // name
+                     str_slice_ty]; // name
         tydesc.set_struct_body(elems, false);
 
         tydesc
index bdb23aea06708acd655c29132a739bb99b6b31ae..1e6f5fe870be321b74df6f78cf03f976afef45a0 100644 (file)
 
 use middle::const_eval;
 use middle::def;
-use middle::subst;
+use middle::lang_items::FnMutTraitLangItem;
 use middle::subst::{Subst, Substs};
-use middle::ty::{ty_param_substs_and_ty};
+use middle::subst;
+use middle::ty::ty_param_substs_and_ty;
 use middle::ty;
-use middle::typeck::rscope;
-use middle::typeck::rscope::{RegionScope};
 use middle::typeck::lookup_def_tcx;
+use middle::typeck::rscope::RegionScope;
+use middle::typeck::rscope;
 use util::ppaux::Repr;
 
 use std::rc::Rc;
@@ -469,6 +470,38 @@ fn ast_ty_to_mt<AC:AstConv, RS:RegionScope>(this: &AC,
     ty::mt {ty: ast_ty_to_ty(this, rscope, ty), mutbl: ast::MutImmutable}
 }
 
+pub fn trait_ref_for_unboxed_function<AC:AstConv,
+                                      RS:RegionScope>(
+                                      this: &AC,
+                                      rscope: &RS,
+                                      unboxed_function: &ast::UnboxedFnTy)
+                                      -> ty::TraitRef {
+    let fn_mut_trait_did = this.tcx()
+                               .lang_items
+                               .require(FnMutTraitLangItem)
+                               .unwrap();
+    let input_types =
+        unboxed_function.decl
+                        .inputs
+                        .iter()
+                        .map(|input| {
+                            ast_ty_to_ty(this, rscope, input.ty)
+                        }).collect::<Vec<_>>();
+    let input_tuple = ty::mk_tup(this.tcx(), input_types);
+    let output_type = ast_ty_to_ty(this,
+                                   rscope,
+                                   unboxed_function.decl.output);
+    let substs = subst::Substs {
+        self_ty: None,
+        tps: vec!(input_tuple, output_type),
+        regions: subst::NonerasedRegions(Vec::new()),
+    };
+    ty::TraitRef {
+        def_id: fn_mut_trait_did,
+        substs: substs,
+    }
+}
+
 // Handle `~`, `Box`, and `&` being able to mean strs and vecs.
 // If a_seq_ty is a str or a vec, make it a str/vec.
 // Also handle first-class trait types.
@@ -491,6 +524,32 @@ fn mk_pointer<AC:AstConv,
             }
             return constr(ty::mk_vec(tcx, mt, None));
         }
+        ast::TyUnboxedFn(ref unboxed_function) => {
+            let trait_store = match ptr_ty {
+                Uniq => ty::UniqTraitStore,
+                RPtr(r) => {
+                    ty::RegionTraitStore(r, a_seq_ty.mutbl)
+                }
+                _ => {
+                    tcx.sess.span_err(
+                        a_seq_ty.ty.span,
+                        "~trait or &trait are the only supported \
+                         forms of casting-to-trait");
+                    return ty::mk_err();
+                }
+            };
+            let ty::TraitRef {
+                def_id,
+                substs
+            } = trait_ref_for_unboxed_function(this,
+                                               rscope,
+                                               *unboxed_function);
+            return ty::mk_trait(this.tcx(),
+                                def_id,
+                                substs,
+                                trait_store,
+                                ty::empty_builtin_bounds());
+        }
         ast::TyPath(ref path, ref bounds, id) => {
             // Note that the "bounds must be empty if path is not a trait"
             // restriction is enforced in the below case for ty_path, which
@@ -528,7 +587,10 @@ fn mk_pointer<AC:AstConv,
                             return ty::mk_err();
                         }
                     };
-                    let bounds = conv_builtin_bounds(this.tcx(), bounds, trait_store);
+                    let bounds = conv_builtin_bounds(this.tcx(),
+                                                     path.span,
+                                                     bounds,
+                                                     trait_store);
                     return ty::mk_trait(tcx,
                                         result.def_id,
                                         result.substs.clone(),
@@ -621,7 +683,10 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
 
                 // Use corresponding trait store to figure out default bounds
                 // if none were specified.
-                let bounds = conv_builtin_bounds(this.tcx(), &f.bounds, store);
+                let bounds = conv_builtin_bounds(this.tcx(),
+                                                 ast_ty.span,
+                                                 &f.bounds,
+                                                 store);
 
                 let fn_decl = ty_of_closure(this,
                                             ast_ty.id,
@@ -636,7 +701,10 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
             ast::TyProc(ref f) => {
                 // Use corresponding trait store to figure out default bounds
                 // if none were specified.
-                let bounds = conv_builtin_bounds(this.tcx(), &f.bounds, ty::UniqTraitStore);
+                let bounds = conv_builtin_bounds(this.tcx(),
+                                                 ast_ty.span,
+                                                 &f.bounds,
+                                                 ty::UniqTraitStore);
 
                 let fn_decl = ty_of_closure(this,
                                             ast_ty.id,
@@ -648,6 +716,11 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
                                             None);
                 ty::mk_closure(tcx, fn_decl)
             }
+            ast::TyUnboxedFn(_) => {
+                tcx.sess.span_err(ast_ty.span,
+                                  "cannot use unboxed functions here");
+                ty::mk_err()
+            }
             ast::TyPath(ref path, ref bounds, id) => {
                 let a_def = match tcx.def_map.borrow().find(&id) {
                     None => {
@@ -891,7 +964,9 @@ pub fn ty_of_closure<AC:AstConv>(
     }
 }
 
-fn conv_builtin_bounds(tcx: &ty::ctxt, ast_bounds: &Option<OwnedSlice<ast::TyParamBound>>,
+fn conv_builtin_bounds(tcx: &ty::ctxt,
+                       span: Span,
+                       ast_bounds: &Option<OwnedSlice<ast::TyParamBound>>,
                        store: ty::TraitStore)
                        -> ty::BuiltinBounds {
     //! Converts a list of bounds from the AST into a `BuiltinBounds`
@@ -928,6 +1003,11 @@ fn conv_builtin_bounds(tcx: &ty::ctxt, ast_bounds: &Option<OwnedSlice<ast::TyPar
                     ast::StaticRegionTyParamBound => {
                         builtin_bounds.add(ty::BoundStatic);
                     }
+                    ast::UnboxedFnTyParamBound(_) => {
+                        tcx.sess.span_err(span,
+                                          "unboxed functions are not allowed \
+                                           here");
+                    }
                     ast::OtherRegionTyParamBound(span) => {
                         if !tcx.sess.features.issue_5723_bootstrap.get() {
                             tcx.sess.span_err(
index 1463cf9602dcae137a104a643e90ea67757697b4..be19c2ef19953a9da32b50258738b23d80b1adba 100644 (file)
@@ -204,7 +204,7 @@ pub fn recurse(&mut self, blk: &ast::Block) -> FnStyleState {
 }
 
 /// Whether `check_binop` is part of an assignment or not.
-/// Used to know wether we allow user overloads and to print
+/// Used to know whether we allow user overloads and to print
 /// better messages on error.
 #[deriving(PartialEq)]
 enum IsBinopAssignment{
@@ -3702,7 +3702,7 @@ pub fn check_const_with_ty(fcx: &FnCtxt,
                            e: &ast::Expr,
                            declty: ty::t) {
     // Gather locals in statics (because of block expressions).
-    // This is technically uneccessary because locals in static items are forbidden,
+    // This is technically unnecessary because locals in static items are forbidden,
     // but prevents type checking from blowing up before const checking can properly
     // emit a error.
     GatherLocalsVisitor { fcx: fcx }.visit_expr(e, ());
@@ -4174,7 +4174,7 @@ pub fn instantiate_path(fcx: &FnCtxt,
                 }
                 None => {
                     fcx.tcx().sess.span_bug(span,
-                        "missing default for a not explicitely provided type param")
+                        "missing default for a not explicitly provided type param")
                 }
             }
         }
index 99a6aad715ccbf548c9f1895e3a6b58f77a5651b..2c0593184786e961ec20fad955d4df55666a92db 100644 (file)
@@ -52,9 +52,7 @@
 use std::rc::Rc;
 
 struct UniversalQuantificationResult {
-    monotype: t,
-    type_variables: Vec<ty::t> ,
-    type_param_defs: Rc<Vec<ty::TypeParameterDef> >
+    monotype: t
 }
 
 fn get_base_type(inference_context: &InferCtxt,
@@ -515,9 +513,7 @@ fn universally_quantify_polytype(&self, polytype: ty_param_bounds_and_ty)
         let monotype = polytype.ty.subst(self.crate_context.tcx, &substitutions);
 
         UniversalQuantificationResult {
-            monotype: monotype,
-            type_variables: substitutions.tps,
-            type_param_defs: polytype.generics.type_param_defs.clone()
+            monotype: monotype
         }
     }
 
index c6bc6ce72974052cc40b7143650ad0e8efa98547..edb7f589e952305bee2428335c1efbb3e510f5d3 100644 (file)
 use util::ppaux;
 use util::ppaux::Repr;
 
-use std::rc::Rc;
 use std::collections::{HashMap, HashSet};
-
+use std::rc::Rc;
 use syntax::abi;
-use syntax::ast::{StaticRegionTyParamBound, OtherRegionTyParamBound,
-                  TraitTyParamBound};
+use syntax::ast::{StaticRegionTyParamBound, OtherRegionTyParamBound};
+use syntax::ast::{TraitTyParamBound, UnboxedFnTyParamBound};
 use syntax::ast;
 use syntax::ast_map;
 use syntax::ast_util::{local_def, split_trait_methods};
 use syntax::codemap::Span;
 use syntax::codemap;
+use syntax::owned_slice::OwnedSlice;
 use syntax::parse::token::special_idents;
 use syntax::parse::token;
 use syntax::print::pprust::{path_to_str};
 use syntax::visit;
-use syntax::owned_slice::OwnedSlice;
 
 struct CollectItemTypesVisitor<'a> {
     ccx: &'a CrateCtxt<'a>
@@ -1114,6 +1113,20 @@ fn compute_bounds(
                     param_bounds.builtin_bounds.add(ty::BoundStatic);
                 }
 
+                UnboxedFnTyParamBound(ref unboxed_function) => {
+                    let rscope = ExplicitRscope;
+                    let mut trait_ref =
+                        astconv::trait_ref_for_unboxed_function(
+                            ccx,
+                            &rscope,
+                            unboxed_function);
+                    let self_ty = ty::mk_param(ccx.tcx,
+                                               param_ty.idx,
+                                               param_ty.def_id);
+                    trait_ref.substs.self_ty = Some(self_ty);
+                    param_bounds.trait_bounds.push(Rc::new(trait_ref));
+                }
+
                 OtherRegionTyParamBound(span) => {
                     if !ccx.tcx.sess.features.issue_5723_bootstrap.get() {
                         ccx.tcx.sess.span_err(
index 4a2cd7cbec2a83600842fd000c1d7122478a27ca..c03c7386fb3310648220bba50aa1b8902bf527b5 100644 (file)
@@ -180,7 +180,7 @@ pub fn tys(&self, a: ty::t, b: ty::t) -> CoerceResult {
         self.unpack_actual_value(a, |sty_a| {
             match *sty_a {
                 ty::ty_bare_fn(ref a_f) => {
-                    // Bare functions are coercable to any closure type.
+                    // Bare functions are coercible to any closure type.
                     //
                     // FIXME(#3320) this should go away and be
                     // replaced with proper inference, got a patch
index 2e8698e59aa9ac7d12e06af532924857758ae64e..5099cc9c5a858c72f19c0ff0c38644fde0429e60 100644 (file)
@@ -372,7 +372,7 @@ fn argvecs<C:Combine>(this: &C, a_args: &[ty::t], b_args: &[ty::t]) -> cres<Vec<
 
 pub fn super_tys<C:Combine>(this: &C, a: ty::t, b: ty::t) -> cres<ty::t> {
 
-    // This is a horible hack - historically, [T] was not treated as a type,
+    // This is a horrible hack - historically, [T] was not treated as a type,
     // so, for example, &T and &[U] should not unify. In fact the only thing
     // &[U] should unify with is &[T]. We preserve that behaviour with this
     // check.
index 6464b191b76911b431cdabbb970ef4af4d9ae57f..14261aef60c085b0dcdbcd1ef0b398886de098c9 100644 (file)
@@ -17,7 +17,7 @@
 the relevant line of code has been type-checked. Therefore, there is
 an elaborate system to track why a particular constraint in the
 inference graph arose so that we can explain to the user what gave
-rise to a patricular error.
+rise to a particular error.
 
 The basis of the system are the "origin" types. An "origin" is the
 reason that a constraint or inference variable arose. There are
@@ -909,6 +909,9 @@ fn rebuild_ty_param_bounds(&self,
             match tpb {
                 &ast::StaticRegionTyParamBound => ast::StaticRegionTyParamBound,
                 &ast::OtherRegionTyParamBound(s) => ast::OtherRegionTyParamBound(s),
+                &ast::UnboxedFnTyParamBound(unboxed_function_type) => {
+                    ast::UnboxedFnTyParamBound(unboxed_function_type)
+                }
                 &ast::TraitTyParamBound(ref tr) => {
                     let last_seg = tr.path.segments.last().unwrap();
                     let mut insert = Vec::new();
index 5f2378bf422a42dc073a385dc630a7238507746c..6455344cb1351de4a88e00c10cd76dfb91cabcc1 100644 (file)
@@ -19,7 +19,7 @@
  * The code in here is defined quite generically so that it can be
  * applied both to type variables, which represent types being inferred,
  * and fn variables, which represent function types being inferred.
- * It may eventually be applied to ther types as well, who knows.
+ * It may eventually be applied to their types as well, who knows.
  * In some cases, the functions are also generic with respect to the
  * operation on the lattice (GLB vs LUB).
  *
index 1170244fbec7d2629dbab48c36da0ae443163a71..a64f7896cfbfd26821fc71cb9c6e4ed7c753acb8 100644 (file)
@@ -362,7 +362,7 @@ fn foo() { // 'foo is the function body
 Note that such components must consist solely of region variables; all
 of these variables can effectively be unified into a single variable.
 Once SCCs are removed, we are left with a DAG.  At this point, we
-could walk the DAG in toplogical order once to compute the expanding
+could walk the DAG in topological order once to compute the expanding
 nodes, and again in reverse topological order to compute the
 contracting nodes. However, as I said, this does not work given the
 current treatment of closure bounds, but perhaps in the future we can
@@ -617,7 +617,7 @@ fn<a,b>(&a, &b, &a) fn<x,y>(&x, &y, &y) fn<a>(&a, &a, &a) fn<a,b,c>(&a,&b,&c)
 contains 'intermediate' variables created to represent the LUB/GLB of
 individual regions.  Basically, when asked to compute the LUB/GLB of a
 region variable with another region, the inferencer cannot oblige
-immediately since the valuese of that variables are not known.
+immediately since the values of that variables are not known.
 Therefore, it creates a new variable that is related to the two
 regions.  For example, the LUB of two variables `$x` and `$y` is a
 fresh variable `$z` that is constrained such that `$x <= $z` and `$y
index 04244ff31a8c31923db9bc647e9efd1414dbd46d..04d7781668cc78753f628be38ebf6db616cecd89 100644 (file)
@@ -271,7 +271,6 @@ enum ParamKind { TypeParam, RegionParam, SelfParam }
 struct InferredInfo<'a> {
     item_id: ast::NodeId,
     kind: ParamKind,
-    index: uint,
     param_id: ast::NodeId,
     term: VarianceTermPtr<'a>,
 }
@@ -310,7 +309,6 @@ fn add_inferred(&mut self,
         let term = self.arena.alloc(|| InferredTerm(inf_index));
         self.inferred_infos.push(InferredInfo { item_id: item_id,
                                                 kind: kind,
-                                                index: index,
                                                 param_id: param_id,
                                                 term: term });
         let newly_added = self.inferred_map.insert(param_id, inf_index);
@@ -485,7 +483,7 @@ fn visit_item(&mut self, item: &ast::Item, _: ()) {
                     let variant =
                         ty::VariantInfo::from_ast_variant(tcx,
                                                           ast_variant,
-                                                          /*discrimant*/ 0);
+                                                          /*discriminant*/ 0);
                     for &arg_ty in variant.args.iter() {
                         self.add_constraints_from_ty(arg_ty, self.covariant);
                     }
index ba50a15a82ba7d4ce795c3331689a198ce216309..97ffcf279ae737770234cc0f6aaf42f49e9a364e 100644 (file)
@@ -16,7 +16,7 @@
 
 use std::mem;
 use std::os;
-use std::unstable::dynamic_lib::DynamicLibrary;
+use std::dynamic_lib::DynamicLibrary;
 use syntax::ast;
 use syntax::attr;
 use syntax::visit;
index 5ddae0c1bfef6358a43eb3d1d547e15e52a308a7..08052c03de482e13091348b8e57bd07ebb27fe65 100644 (file)
@@ -42,23 +42,17 @@ pub fn indent<R>(op: || -> R) -> R {
     r
 }
 
-pub struct _indenter {
-    _i: (),
+pub struct Indenter {
+    _cannot_construct_outside_of_this_module: ()
 }
 
-impl Drop for _indenter {
+impl Drop for Indenter {
     fn drop(&mut self) { debug!("<<"); }
 }
 
-pub fn _indenter(_i: ()) -> _indenter {
-    _indenter {
-        _i: ()
-    }
-}
-
-pub fn indenter() -> _indenter {
+pub fn indenter() -> Indenter {
     debug!(">>");
-    _indenter(())
+    Indenter { _cannot_construct_outside_of_this_module: () }
 }
 
 struct LoopQueryVisitor<'a> {
index f0d691823256d5a3a7bd0ec846dafa8553aa79d8..47d9e66fbd5a51325e2ad79a28b24db0ccb2d10d 100644 (file)
@@ -61,12 +61,12 @@ fn add_bytes_to_bits<T: Int + CheckedAdd + ToBits>(bits: T, bytes: T) -> T {
     let (new_high_bits, new_low_bits) = bytes.to_bits();
 
     if new_high_bits > Zero::zero() {
-        fail!("numeric overflow occured.")
+        fail!("numeric overflow occurred.")
     }
 
     match bits.checked_add(&new_low_bits) {
         Some(x) => return x,
-        None => fail!("numeric overflow occured.")
+        None => fail!("numeric overflow occurred.")
     }
 }
 
index 2a4774ffd84d4f5574edc73f1b7ef0c79fe00f4c..d243c61ddaff8ba3d91bdab8fb135e9888352d12 100644 (file)
@@ -203,7 +203,7 @@ fn build_struct(tcx: &ty::ctxt, did: ast::DefId) -> clean::Struct {
 fn build_type(tcx: &ty::ctxt, did: ast::DefId) -> clean::ItemEnum {
     let t = ty::lookup_item_type(tcx, did);
     match ty::get(t.ty).sty {
-        ty::ty_enum(edid, _) => {
+        ty::ty_enum(edid, _) if !csearch::is_typedef(&tcx.sess.cstore, did) => {
             return clean::EnumItem(clean::Enum {
                 generics: t.generics.clean(),
                 variants_stripped: false,
index 650cd749af69e1e8d949f0bc2139887f3d3036f1..54128fda6c6a5fc95b2e7182eba07119b5a8f5dc 100644 (file)
@@ -477,6 +477,10 @@ fn clean(&self) -> TyParamBound {
         match *self {
             ast::StaticRegionTyParamBound => RegionBound,
             ast::OtherRegionTyParamBound(_) => RegionBound,
+            ast::UnboxedFnTyParamBound(_) => {
+                // FIXME(pcwalton): Wrong.
+                RegionBound
+            }
             ast::TraitTyParamBound(ref t) => TraitBound(t.clean()),
         }
     }
index fea6748660bde2c0e2df962032226a7503a7b6e2..8ad10a686e677677778e4ce92efb73b5f6424094 100644 (file)
@@ -135,7 +135,6 @@ fn drop(&mut self) {
 mod imp {
     use libc;
     use std::mem;
-    use std::os::win32::as_utf16_p;
     use std::os;
     use std::ptr;
 
@@ -162,8 +161,9 @@ pub struct Lock {
 
     impl Lock {
         pub fn new(p: &Path) -> Lock {
-            let handle = as_utf16_p(p.as_str().unwrap(), |p| unsafe {
-                libc::CreateFileW(p,
+            let p_16 = p.as_str().unwrap().to_utf16().append_one(0);
+            let handle = unsafe {
+                libc::CreateFileW(p_16.as_ptr(),
                                   libc::FILE_GENERIC_READ |
                                     libc::FILE_GENERIC_WRITE,
                                   libc::FILE_SHARE_READ |
@@ -173,7 +173,7 @@ pub fn new(p: &Path) -> Lock {
                                   libc::CREATE_ALWAYS,
                                   libc::FILE_ATTRIBUTE_NORMAL,
                                   ptr::mut_null())
-            });
+            };
             if handle as uint == libc::INVALID_HANDLE_VALUE as uint {
                 fail!("create file error: {}", os::last_os_error());
             }
index 260d26c543736c754904730f634f791a7ce56e09..6f9a8062be88fe5b6d0ecd27835b7c144bf947ad 100644 (file)
@@ -24,6 +24,7 @@
 //! // ... something using html
 //! ```
 
+#![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
 use libc;
@@ -390,7 +391,7 @@ fn parse_lang_string(string: &str) -> (bool,bool,bool,bool) {
 }
 
 /// By default this markdown renderer generates anchors for each header in the
-/// rendered document. The anchor name is the contents of the header spearated
+/// rendered document. The anchor name is the contents of the header separated
 /// by hyphens, and a task-local map is used to disambiguate among duplicate
 /// headers (numbers are appended).
 ///
index 5bc6d8031ac29754970897aae18b3e904b9b69de..c6d8632082ea7852a01b7449ddaa5869163274f7 100644 (file)
@@ -49,11 +49,11 @@ pub struct TocEntry {
 #[deriving(PartialEq)]
 pub struct TocBuilder {
     top_level: Toc,
-    /// The current heirachy of parent headings, the levels are
+    /// The current hierarchy of parent headings, the levels are
     /// strictly increasing (i.e. chain[0].level < chain[1].level <
-    /// ...) with each entry being the most recent occurance of a
+    /// ...) with each entry being the most recent occurrence of a
     /// heading with that level (it doesn't include the most recent
-    /// occurences of every level, just, if *is* in `chain` then is is
+    /// occurrences of every level, just, if *is* in `chain` then is is
     /// the most recent one).
     ///
     /// We also have `chain[0].level <= top_level.entries[last]`.
@@ -123,7 +123,7 @@ fn fold_until(&mut self, level: u32) {
     }
 
     /// Push a level `level` heading into the appropriate place in the
-    /// heirarchy, returning a string containing the section number in
+    /// hierarchy, returning a string containing the section number in
     /// `<num>.<num>.<num>` format.
     pub fn push<'a>(&'a mut self, level: u32, name: String, id: String) -> &'a str {
         assert!(level >= 1);
index 727258bec8fa1f722afd8b5502c478cd64988449..31eb83cb92015b69b43943c7865deab954a20d47 100644 (file)
@@ -383,7 +383,7 @@ fn should_leave_multiple_indent_levels() {
 
     #[test]
     fn should_ignore_first_line_indent() {
-        // Thi first line of the first paragraph may not be indented as
+        // The first line of the first paragraph may not be indented as
         // far due to the way the doc string was written:
         //
         // #[doc = "Start way over here
index 7a796e97f412f2ee98bf4158a7c05a8a167779a5..fee1d63a274d51ab7530e157bb98d8c0de1e2db1 100644 (file)
@@ -10,7 +10,7 @@
 
 use clean;
 
-use dl = std::unstable::dynamic_lib;
+use dl = std::dynamic_lib;
 use serialize::json;
 use std::string::String;
 
index 3436305829791456662c98b6cc355ced2f88b37d..0d77764127465bcee61ad89cb2aefe8c9579efb5 100644 (file)
@@ -15,7 +15,7 @@
 use std::os;
 use std::str;
 use std::string::String;
-use std::unstable::dynamic_lib::DynamicLibrary;
+use std::dynamic_lib::DynamicLibrary;
 
 use std::collections::{HashSet, HashMap};
 use testing;
index fccbe4a15e948144cf8f67488107da5313951692..eec19e9d5db86bf9cb5ad55587516b9a2b668d40 100644 (file)
@@ -298,10 +298,12 @@ mod os {
         static _PTHREAD_MUTEX_SIG_init: libc::c_long = 0x32AAABA7;
         static _PTHREAD_COND_SIG_init: libc::c_long = 0x3CB0B1BB;
 
+        #[repr(C)]
         pub struct pthread_mutex_t {
             __sig: libc::c_long,
             __opaque: [u8, ..__PTHREAD_MUTEX_SIZE__],
         }
+        #[repr(C)]
         pub struct pthread_cond_t {
             __sig: libc::c_long,
             __opaque: [u8, ..__PTHREAD_COND_SIZE__],
@@ -339,10 +341,12 @@ mod os {
         #[cfg(target_arch = "mips")]
         static __SIZEOF_PTHREAD_COND_T: uint = 48 - 8;
 
+        #[repr(C)]
         pub struct pthread_mutex_t {
             __align: libc::c_longlong,
             size: [u8, ..__SIZEOF_PTHREAD_MUTEX_T],
         }
+        #[repr(C)]
         pub struct pthread_cond_t {
             __align: libc::c_longlong,
             size: [u8, ..__SIZEOF_PTHREAD_COND_T],
@@ -361,7 +365,9 @@ pub struct pthread_cond_t {
     mod os {
         use libc;
 
+        #[repr(C)]
         pub struct pthread_mutex_t { value: libc::c_int }
+        #[repr(C)]
         pub struct pthread_cond_t { value: libc::c_int }
 
         pub static PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
index 0640b2b9c77aeefe06c80b52d7885000becf27e6..bde14b962c7a45020b92ffa3fc630c1ba37c9ccb 100644 (file)
@@ -163,7 +163,7 @@ pub fn run(~self, mut f: ||) -> Box<Task> {
 
         // Here we must unsafely borrow the task in order to not remove it from
         // TLS. When collecting failure, we may attempt to send on a channel (or
-        // just run aribitrary code), so we must be sure to still have a local
+        // just run arbitrary code), so we must be sure to still have a local
         // task in TLS.
         unsafe {
             let me: *mut Task = Local::unsafe_borrow();
index 2fd9f4ef1f18cadf9e6d8ebddcaa24efa058e96d..f7475db1552f7181acd5bd414aca32e0d7ecd290 100644 (file)
@@ -395,7 +395,7 @@ pub fn begin_unwind<M: Any + Send>(msg: M, file: &'static str, line: uint) -> !
 /// The core of the unwinding.
 ///
 /// This is non-generic to avoid instantiation bloat in other crates
-/// (which makes compilation of small crates noticably slower). (Note:
+/// (which makes compilation of small crates noticeably slower). (Note:
 /// we need the `Any` object anyway, we're not just creating it to
 /// avoid being generic.)
 ///
@@ -408,7 +408,7 @@ fn begin_unwind_inner(msg: Box<Any:Send>,
     // First, invoke call the user-defined callbacks triggered on task failure.
     //
     // By the time that we see a callback has been registered (by reading
-    // MAX_CALLBACKS), the actuall callback itself may have not been stored yet,
+    // MAX_CALLBACKS), the actual callback itself may have not been stored yet,
     // so we just chalk it up to a race condition and move on to the next
     // callback. Additionally, CALLBACK_CNT may briefly be higher than
     // MAX_CALLBACKS, so we're sure to clamp it as necessary.
index f5cde39bc8343405cde618df3f69e4a8824fbe0b..fe8935db2ec128278b9c7367ccce085e9513169c 100644 (file)
@@ -18,7 +18,6 @@
 pub struct IdleWatcher {
     handle: *uvll::uv_idle_t,
     idle_flag: bool,
-    closed: bool,
     callback: Box<Callback:Send>,
 }
 
@@ -31,7 +30,6 @@ pub fn new(loop_: &mut Loop, cb: Box<Callback:Send>) -> Box<IdleWatcher> {
         let me = box IdleWatcher {
             handle: handle,
             idle_flag: false,
-            closed: false,
             callback: cb,
         };
         return me.install();
index e2122aea0365ebeb2167df272a4ace6927df9aa8..d67adfe501e62e5db7202c634a238ded8c432461 100644 (file)
@@ -212,7 +212,7 @@ fn new(s: &'static str) -> ForbidSwitch {
 impl Drop for ForbidSwitch {
     fn drop(&mut self) {
         assert!(self.io == homing::local_id(),
-                "didnt want a scheduler switch: {}",
+                "didn't want a scheduler switch: {}",
                 self.msg);
     }
 }
index e7bdc25a1fd91d6bb07ea5021998f1ba52351ccd..47b321b068b36ae6046cd91107d38e428f3e51d0 100644 (file)
@@ -165,7 +165,6 @@ pub struct TcpWatcher {
 pub struct TcpListener {
     home: HomeHandle,
     handle: *uvll::uv_pipe_t,
-    closing_task: Option<BlockedTask>,
     outgoing: Sender<Result<Box<rtio::RtioTcpStream:Send>, IoError>>,
     incoming: Receiver<Result<Box<rtio::RtioTcpStream:Send>, IoError>>,
 }
@@ -358,7 +357,6 @@ pub fn bind(io: &mut UvIoFactory, address: rtio::SocketAddr)
         let l = box TcpListener {
             home: io.make_handle(),
             handle: handle,
-            closing_task: None,
             outgoing: tx,
             incoming: rx,
         };
index 8ce985eb76d658e778a19f90e33ff40d67cd1166..742944977622fa96c0132c22210290b92990d0f3 100644 (file)
@@ -147,7 +147,7 @@ pub fn write(&mut self, buf: &[u8], may_timeout: bool) -> Result<(), UvError> {
         // function is why that wording exists.
         //
         // Implementation-wise, we must be careful when passing a buffer down to
-        // libuv. Most of this implementation avoids allocations becuase of the
+        // libuv. Most of this implementation avoids allocations because of the
         // blocking guarantee (all stack local variables are valid for the
         // entire read/write request). If our write request can be timed out,
         // however, we must heap allocate the data and pass that to the libuv
@@ -164,7 +164,7 @@ pub fn write(&mut self, buf: &[u8], may_timeout: bool) -> Result<(), UvError> {
         };
 
         // Send off the request, but be careful to not block until we're sure
-        // that the write reqeust is queued. If the reqeust couldn't be queued,
+        // that the write request is queued. If the request couldn't be queued,
         // then we should return immediately with an error.
         match unsafe {
             uvll::uv_write(req.handle, self.handle, [uv_buf], write_cb)
index f6c6d6c9068e0cbbfc46a43811f50d22dd183382..a6193dd9379c1636734f8428338848c8534e0b7a 100644 (file)
@@ -136,6 +136,7 @@ pub struct uv_process_options_t {
 
 // These fields are private because they must be interfaced with through the
 // functions below.
+#[repr(C)]
 pub struct uv_stdio_container_t {
     flags: libc::c_int,
     stream: *uv_stream_t,
index a780b63bfd0269c767732ea51d6690d04caa789d..34851265409ec495b8afbdb907ef75669056a226 100644 (file)
@@ -393,7 +393,7 @@ pub fn mut_iter<'a>(&'a mut self) -> MutEntries<'a, K, V> {
         }
 
         pub fn move_iter(self) -> MoveEntries<K, V> {
-            MoveEntries { table: self, idx: 0, elems_seen: 0 }
+            MoveEntries { table: self, idx: 0 }
         }
     }
 
@@ -428,8 +428,7 @@ pub struct MutEntries<'a, K, V> {
     /// Iterator over the entries in a table, consuming the table.
     pub struct MoveEntries<K, V> {
         table: RawTable<K, V>,
-        idx: uint,
-        elems_seen: uint,
+        idx: uint
     }
 
     impl<'a, K, V> Iterator<(&'a K, &'a V)> for Entries<'a, K, V> {
index 170618e276b2c8f4ac58a42e56e834a51870063b..ffb2a0dbed8f90c97bea4cb8a1ea9aca1f3f5f5c 100644 (file)
@@ -542,7 +542,7 @@ pub fn send(&self, t: T) {
     /// ```
     pub fn send_opt(&self, t: T) -> Result<(), T> {
         // In order to prevent starvation of other tasks in situations where
-        // a task sends repeatedly without ever receiving, we occassionally
+        // a task sends repeatedly without ever receiving, we occasionally
         // yield instead of doing a send immediately.
         //
         // Don't unconditionally attempt to yield because the TLS overhead can
diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs
new file mode 100644 (file)
index 0000000..fa6efc8
--- /dev/null
@@ -0,0 +1,332 @@
+// Copyright 2013-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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/*!
+
+Dynamic library facilities.
+
+A simple wrapper over the platform's dynamic library facilities
+
+*/
+
+#![experimental]
+#![allow(missing_doc)]
+
+use clone::Clone;
+use c_str::ToCStr;
+use iter::Iterator;
+use mem;
+use ops::*;
+use option::*;
+use os;
+use path::{Path,GenericPath};
+use result::*;
+use slice::{Vector,ImmutableVector};
+use str;
+use string::String;
+use vec::Vec;
+
+pub struct DynamicLibrary { handle: *u8}
+
+impl Drop for DynamicLibrary {
+    fn drop(&mut self) {
+        match dl::check_for_errors_in(|| {
+            unsafe {
+                dl::close(self.handle)
+            }
+        }) {
+            Ok(()) => {},
+            Err(str) => fail!("{}", str)
+        }
+    }
+}
+
+impl DynamicLibrary {
+    // FIXME (#12938): Until DST lands, we cannot decompose &str into
+    // & and str, so we cannot usefully take ToCStr arguments by
+    // reference (without forcing an additional & around &str). So we
+    // are instead temporarily adding an instance for &Path, so that
+    // we can take ToCStr as owned. When DST lands, the &Path instance
+    // should be removed, and arguments bound by ToCStr should be
+    // passed by reference. (Here: in the `open` method.)
+
+    /// Lazily open a dynamic library. When passed None it gives a
+    /// handle to the calling process
+    pub fn open<T: ToCStr>(filename: Option<T>)
+                        -> Result<DynamicLibrary, String> {
+        unsafe {
+            let mut filename = filename;
+            let maybe_library = dl::check_for_errors_in(|| {
+                match filename.take() {
+                    Some(name) => dl::open_external(name),
+                    None => dl::open_internal()
+                }
+            });
+
+            // The dynamic library must not be constructed if there is
+            // an error opening the library so the destructor does not
+            // run.
+            match maybe_library {
+                Err(err) => Err(err),
+                Ok(handle) => Ok(DynamicLibrary { handle: handle })
+            }
+        }
+    }
+
+    /// Prepends a path to this process's search path for dynamic libraries
+    pub fn prepend_search_path(path: &Path) {
+        let mut search_path = DynamicLibrary::search_path();
+        search_path.insert(0, path.clone());
+        let newval = DynamicLibrary::create_path(search_path.as_slice());
+        os::setenv(DynamicLibrary::envvar(),
+                   str::from_utf8(newval.as_slice()).unwrap());
+    }
+
+    /// From a slice of paths, create a new vector which is suitable to be an
+    /// environment variable for this platforms dylib search path.
+    pub fn create_path(path: &[Path]) -> Vec<u8> {
+        let mut newvar = Vec::new();
+        for (i, path) in path.iter().enumerate() {
+            if i > 0 { newvar.push(DynamicLibrary::separator()); }
+            newvar.push_all(path.as_vec());
+        }
+        return newvar;
+    }
+
+    /// Returns the environment variable for this process's dynamic library
+    /// search path
+    pub fn envvar() -> &'static str {
+        if cfg!(windows) {
+            "PATH"
+        } else if cfg!(target_os = "macos") {
+            "DYLD_LIBRARY_PATH"
+        } else {
+            "LD_LIBRARY_PATH"
+        }
+    }
+
+    fn separator() -> u8 {
+        if cfg!(windows) {';' as u8} else {':' as u8}
+    }
+
+    /// Returns the current search path for dynamic libraries being used by this
+    /// process
+    pub fn search_path() -> Vec<Path> {
+        let mut ret = Vec::new();
+        match os::getenv_as_bytes(DynamicLibrary::envvar()) {
+            Some(env) => {
+                for portion in
+                        env.as_slice()
+                           .split(|a| *a == DynamicLibrary::separator()) {
+                    ret.push(Path::new(portion));
+                }
+            }
+            None => {}
+        }
+        return ret;
+    }
+
+    /// Access the value at the symbol of the dynamic library
+    pub unsafe fn symbol<T>(&self, symbol: &str) -> Result<T, String> {
+        // This function should have a lifetime constraint of 'a on
+        // T but that feature is still unimplemented
+
+        let maybe_symbol_value = dl::check_for_errors_in(|| {
+            symbol.with_c_str(|raw_string| {
+                dl::symbol(self.handle, raw_string)
+            })
+        });
+
+        // The value must not be constructed if there is an error so
+        // the destructor does not run.
+        match maybe_symbol_value {
+            Err(err) => Err(err),
+            Ok(symbol_value) => Ok(mem::transmute(symbol_value))
+        }
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+    use prelude::*;
+    use libc;
+
+    #[test]
+    #[ignore(cfg(windows))] // FIXME #8818
+    #[ignore(cfg(target_os="android"))] // FIXME(#10379)
+    fn test_loading_cosine() {
+        // The math library does not need to be loaded since it is already
+        // statically linked in
+        let none: Option<Path> = None; // appease the typechecker
+        let libm = match DynamicLibrary::open(none) {
+            Err(error) => fail!("Could not load self as module: {}", error),
+            Ok(libm) => libm
+        };
+
+        let cosine: extern fn(libc::c_double) -> libc::c_double = unsafe {
+            match libm.symbol("cos") {
+                Err(error) => fail!("Could not load function cos: {}", error),
+                Ok(cosine) => cosine
+            }
+        };
+
+        let argument = 0.0;
+        let expected_result = 1.0;
+        let result = cosine(argument);
+        if result != expected_result {
+            fail!("cos({:?}) != {:?} but equaled {:?} instead", argument,
+                   expected_result, result)
+        }
+    }
+
+    #[test]
+    #[cfg(target_os = "linux")]
+    #[cfg(target_os = "macos")]
+    #[cfg(target_os = "freebsd")]
+    fn test_errors_do_not_crash() {
+        // Open /dev/null as a library to get an error, and make sure
+        // that only causes an error, and not a crash.
+        let path = Path::new("/dev/null");
+        match DynamicLibrary::open(Some(&path)) {
+            Err(_) => {}
+            Ok(_) => fail!("Successfully opened the empty library.")
+        }
+    }
+}
+
+#[cfg(target_os = "linux")]
+#[cfg(target_os = "android")]
+#[cfg(target_os = "macos")]
+#[cfg(target_os = "freebsd")]
+pub mod dl {
+    use prelude::*;
+
+    use c_str::{CString, ToCStr};
+    use libc;
+    use ptr;
+    use result::*;
+    use str::StrAllocating;
+    use string::String;
+
+    pub unsafe fn open_external<T: ToCStr>(filename: T) -> *u8 {
+        filename.with_c_str(|raw_name| {
+            dlopen(raw_name, Lazy as libc::c_int) as *u8
+        })
+    }
+
+    pub unsafe fn open_internal() -> *u8 {
+        dlopen(ptr::null(), Lazy as libc::c_int) as *u8
+    }
+
+    pub fn check_for_errors_in<T>(f: || -> T) -> Result<T, String> {
+        use rt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
+        static mut lock: StaticNativeMutex = NATIVE_MUTEX_INIT;
+        unsafe {
+            // dlerror isn't thread safe, so we need to lock around this entire
+            // sequence
+            let _guard = lock.lock();
+            let _old_error = dlerror();
+
+            let result = f();
+
+            let last_error = dlerror();
+            let ret = if ptr::null() == last_error {
+                Ok(result)
+            } else {
+                Err(CString::new(last_error, false).as_str()
+                                                   .unwrap()
+                                                   .to_string())
+            };
+
+            ret
+        }
+    }
+
+    pub unsafe fn symbol(handle: *u8, symbol: *libc::c_char) -> *u8 {
+        dlsym(handle as *libc::c_void, symbol) as *u8
+    }
+    pub unsafe fn close(handle: *u8) {
+        dlclose(handle as *libc::c_void); ()
+    }
+
+    pub enum RTLD {
+        Lazy = 1,
+        Now = 2,
+        Global = 256,
+        Local = 0,
+    }
+
+    #[link_name = "dl"]
+    extern {
+        fn dlopen(filename: *libc::c_char, flag: libc::c_int) -> *libc::c_void;
+        fn dlerror() -> *libc::c_char;
+        fn dlsym(handle: *libc::c_void, symbol: *libc::c_char) -> *libc::c_void;
+        fn dlclose(handle: *libc::c_void) -> libc::c_int;
+    }
+}
+
+#[cfg(target_os = "win32")]
+pub mod dl {
+    use c_str::ToCStr;
+    use libc;
+    use os;
+    use ptr;
+    use result::{Ok, Err, Result};
+    use str::StrAllocating;
+    use str;
+    use string::String;
+
+    pub unsafe fn open_external<T: ToCStr>(filename: T) -> *u8 {
+        // Windows expects Unicode data
+        let filename_cstr = filename.to_c_str();
+        let filename_str = str::from_utf8(filename_cstr.as_bytes_no_nul()).unwrap();
+        let filename_str = filename_str.to_utf16().append_one(0);
+        LoadLibraryW(filename_str.as_ptr() as *libc::c_void) as *u8
+    }
+
+    pub unsafe fn open_internal() -> *u8 {
+        let handle = ptr::null();
+        GetModuleHandleExW(0 as libc::DWORD, ptr::null(), &handle as **libc::c_void);
+        handle as *u8
+    }
+
+    pub fn check_for_errors_in<T>(f: || -> T) -> Result<T, String> {
+        unsafe {
+            SetLastError(0);
+
+            let result = f();
+
+            let error = os::errno();
+            if 0 == error {
+                Ok(result)
+            } else {
+                Err(format!("Error code {}", error))
+            }
+        }
+    }
+
+    pub unsafe fn symbol(handle: *u8, symbol: *libc::c_char) -> *u8 {
+        GetProcAddress(handle as *libc::c_void, symbol) as *u8
+    }
+    pub unsafe fn close(handle: *u8) {
+        FreeLibrary(handle as *libc::c_void); ()
+    }
+
+    #[allow(non_snake_case_functions)]
+    extern "system" {
+        fn SetLastError(error: libc::size_t);
+        fn LoadLibraryW(name: *libc::c_void) -> *libc::c_void;
+        fn GetModuleHandleExW(dwFlags: libc::DWORD, name: *u16,
+                              handle: **libc::c_void) -> *libc::c_void;
+        fn GetProcAddress(handle: *libc::c_void, name: *libc::c_char) -> *libc::c_void;
+        fn FreeLibrary(handle: *libc::c_void);
+    }
+}
index 6f3eec01e8e34678b8ed133e57422e44021680ba..a1e0fa889789f39b3b59a1f3a50c6cdd781d1641 100644 (file)
 
 * Make a simple TCP client connection and request
 
-    ```rust,should_fail
+    ```rust
     # #![allow(unused_must_use)]
     use std::io::net::tcp::TcpStream;
 
+    # // connection doesn't fail if a server is running on 8080
+    # // locally, we still want to be type checking this code, so lets
+    # // just stop it running (#11576)
+    # if false {
     let mut socket = TcpStream::connect("127.0.0.1", 8080).unwrap();
     socket.write(bytes!("GET / HTTP/1.0\n\n"));
     let response = socket.read_to_end();
+    # }
     ```
 
 * Make a simple TCP server
index 85813c02d5535be8c25e49515123caf37260e805..e147997334ccc4259296366d347a96c18824c427 100644 (file)
@@ -241,15 +241,12 @@ fn start(argc: int, argv: **u8) -> int {
 /* Runtime and platform support */
 
 pub mod c_vec;
+pub mod dynamic_lib;
 pub mod os;
 pub mod io;
 pub mod path;
 pub mod fmt;
 
-// Private APIs
-#[unstable]
-pub mod unstable;
-
 // FIXME #7809: This shouldn't be pub, and it should be reexported under 'unstable'
 // but name resolution doesn't work without it being pub.
 #[unstable]
@@ -279,3 +276,11 @@ mod std {
     // The test runner requires std::slice::Vector, so re-export std::slice just for it.
     #[cfg(test)] pub use slice;
 }
+
+#[deprecated]
+#[allow(missing_doc)]
+#[doc(hiden)]
+pub mod unstable {
+    #[deprecated = "use std::dynamic_lib"]
+    pub use dynamic_lib;
+}
index 90df18106f0a5b758f8a0ecf18e321ed830b346f..fa882e7d016fe21783efe91b2ed1cebd09c62af4 100644 (file)
@@ -133,7 +133,7 @@ pub mod win32 {
     use os::TMPBUF_SZ;
     use slice::{MutableVector, ImmutableVector};
     use string::String;
-    use str::{StrSlice, StrAllocating};
+    use str::StrSlice;
     use str;
     use vec::Vec;
 
@@ -171,17 +171,6 @@ pub fn fill_utf16_buf_and_decode(f: |*mut u16, DWORD| -> DWORD)
             return res;
         }
     }
-
-    pub fn as_utf16_p<T>(s: &str, f: |*u16| -> T) -> T {
-        as_mut_utf16_p(s, |t| { f(t as *u16) })
-    }
-
-    pub fn as_mut_utf16_p<T>(s: &str, f: |*mut u16| -> T) -> T {
-        let mut t = s.to_utf16();
-        // Null terminate before passing on.
-        t.push(0u16);
-        f(t.as_mut_ptr())
-    }
 }
 
 /*
@@ -356,11 +345,10 @@ pub fn getenv_as_bytes(n: &str) -> Option<Vec<u8>> {
 pub fn getenv(n: &str) -> Option<String> {
     unsafe {
         with_env_lock(|| {
-            use os::win32::{as_utf16_p, fill_utf16_buf_and_decode};
-            as_utf16_p(n, |u| {
-                fill_utf16_buf_and_decode(|buf, sz| {
-                    libc::GetEnvironmentVariableW(u, buf, sz)
-                })
+            use os::win32::{fill_utf16_buf_and_decode};
+            let n = n.to_utf16().append_one(0);
+            fill_utf16_buf_and_decode(|buf, sz| {
+                libc::GetEnvironmentVariableW(n.as_ptr(), buf, sz)
             })
         })
     }
@@ -398,14 +386,11 @@ pub fn setenv(n: &str, v: &str) {
 /// Sets the environment variable `n` to the value `v` for the currently running
 /// process
 pub fn setenv(n: &str, v: &str) {
+    let n = n.to_utf16().append_one(0);
+    let v = v.to_utf16().append_one(0);
     unsafe {
         with_env_lock(|| {
-            use os::win32::as_utf16_p;
-            as_utf16_p(n, |nbuf| {
-                as_utf16_p(v, |vbuf| {
-                    libc::SetEnvironmentVariableW(nbuf, vbuf);
-                })
-            })
+            libc::SetEnvironmentVariableW(n.as_ptr(), v.as_ptr());
         })
     }
 }
@@ -428,12 +413,10 @@ fn _unsetenv(n: &str) {
     }
     #[cfg(windows)]
     fn _unsetenv(n: &str) {
+        let n = n.to_utf16().append_one(0);
         unsafe {
             with_env_lock(|| {
-                use os::win32::as_utf16_p;
-                as_utf16_p(n, |nbuf| {
-                    libc::SetEnvironmentVariableW(nbuf, ptr::null());
-                })
+                libc::SetEnvironmentVariableW(n.as_ptr(), ptr::null());
             })
         }
     }
@@ -732,11 +715,12 @@ pub fn change_dir(p: &Path) -> bool {
 
     #[cfg(windows)]
     fn chdir(p: &Path) -> bool {
+        let p = match p.as_str() {
+            Some(s) => s.to_utf16().append_one(0),
+            None => return false,
+        };
         unsafe {
-            use os::win32::as_utf16_p;
-            return as_utf16_p(p.as_str().unwrap(), |buf| {
-                libc::SetCurrentDirectoryW(buf) != (0 as libc::BOOL)
-            });
+            libc::SetCurrentDirectoryW(p.as_ptr()) != (0 as libc::BOOL)
         }
     }
 
index 83fc95267afdf3333d82335e367bf18e793514c5..a1372b51d472a51e5e1b5bc8785d15ffd2e0451c 100644 (file)
@@ -325,6 +325,7 @@ pub fn write(w: &mut Writer) -> IoResult<()> {
     #[cfg(target_os = "macos")]
     fn print(w: &mut Writer, idx: int, addr: *libc::c_void) -> IoResult<()> {
         use intrinsics;
+        #[repr(C)]
         struct Dl_info {
             dli_fname: *libc::c_char,
             dli_fbase: *libc::c_void,
@@ -614,7 +615,7 @@ mod imp {
     use rt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
     use slice::ImmutableVector;
     use str::StrSlice;
-    use unstable::dynamic_lib::DynamicLibrary;
+    use dynamic_lib::DynamicLibrary;
 
     #[allow(non_snake_case_functions)]
     extern "system" {
index 9ee62ee3d81b6c5269e1b2ecc06d5c4b993ea5ea..a4e1ad84252b1295a2154af3f65bac1ad747dd53 100644 (file)
@@ -84,7 +84,7 @@ pub struct TaskBuilder {
     /// Options to spawn the new task with
     pub opts: TaskOpts,
     gen_body: Option<proc(v: proc():Send):Send -> proc():Send>,
-    nocopy: Option<marker::NoCopy>,
+    nocopy: marker::NoCopy,
 }
 
 impl TaskBuilder {
@@ -94,7 +94,7 @@ pub fn new() -> TaskBuilder {
         TaskBuilder {
             opts: TaskOpts::new(),
             gen_body: None,
-            nocopy: None,
+            nocopy: marker::NoCopy,
         }
     }
 
diff --git a/src/libstd/unstable/dynamic_lib.rs b/src/libstd/unstable/dynamic_lib.rs
deleted file mode 100644 (file)
index c05cdc8..0000000
+++ /dev/null
@@ -1,329 +0,0 @@
-// Copyright 2013-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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-Dynamic library facilities.
-
-A simple wrapper over the platform's dynamic library facilities
-
-*/
-
-use clone::Clone;
-use c_str::ToCStr;
-use iter::Iterator;
-use mem;
-use ops::*;
-use option::*;
-use os;
-use path::{Path,GenericPath};
-use result::*;
-use slice::{Vector,ImmutableVector};
-use str;
-use string::String;
-use vec::Vec;
-
-pub struct DynamicLibrary { handle: *u8}
-
-impl Drop for DynamicLibrary {
-    fn drop(&mut self) {
-        match dl::check_for_errors_in(|| {
-            unsafe {
-                dl::close(self.handle)
-            }
-        }) {
-            Ok(()) => {},
-            Err(str) => fail!("{}", str)
-        }
-    }
-}
-
-impl DynamicLibrary {
-    // FIXME (#12938): Until DST lands, we cannot decompose &str into
-    // & and str, so we cannot usefully take ToCStr arguments by
-    // reference (without forcing an additional & around &str). So we
-    // are instead temporarily adding an instance for &Path, so that
-    // we can take ToCStr as owned. When DST lands, the &Path instance
-    // should be removed, and arguments bound by ToCStr should be
-    // passed by reference. (Here: in the `open` method.)
-
-    /// Lazily open a dynamic library. When passed None it gives a
-    /// handle to the calling process
-    pub fn open<T: ToCStr>(filename: Option<T>)
-                        -> Result<DynamicLibrary, String> {
-        unsafe {
-            let mut filename = filename;
-            let maybe_library = dl::check_for_errors_in(|| {
-                match filename.take() {
-                    Some(name) => dl::open_external(name),
-                    None => dl::open_internal()
-                }
-            });
-
-            // The dynamic library must not be constructed if there is
-            // an error opening the library so the destructor does not
-            // run.
-            match maybe_library {
-                Err(err) => Err(err),
-                Ok(handle) => Ok(DynamicLibrary { handle: handle })
-            }
-        }
-    }
-
-    /// Prepends a path to this process's search path for dynamic libraries
-    pub fn prepend_search_path(path: &Path) {
-        let mut search_path = DynamicLibrary::search_path();
-        search_path.insert(0, path.clone());
-        let newval = DynamicLibrary::create_path(search_path.as_slice());
-        os::setenv(DynamicLibrary::envvar(),
-                   str::from_utf8(newval.as_slice()).unwrap());
-    }
-
-    /// From a slice of paths, create a new vector which is suitable to be an
-    /// environment variable for this platforms dylib search path.
-    pub fn create_path(path: &[Path]) -> Vec<u8> {
-        let mut newvar = Vec::new();
-        for (i, path) in path.iter().enumerate() {
-            if i > 0 { newvar.push(DynamicLibrary::separator()); }
-            newvar.push_all(path.as_vec());
-        }
-        return newvar;
-    }
-
-    /// Returns the environment variable for this process's dynamic library
-    /// search path
-    pub fn envvar() -> &'static str {
-        if cfg!(windows) {
-            "PATH"
-        } else if cfg!(target_os = "macos") {
-            "DYLD_LIBRARY_PATH"
-        } else {
-            "LD_LIBRARY_PATH"
-        }
-    }
-
-    fn separator() -> u8 {
-        if cfg!(windows) {';' as u8} else {':' as u8}
-    }
-
-    /// Returns the current search path for dynamic libraries being used by this
-    /// process
-    pub fn search_path() -> Vec<Path> {
-        let mut ret = Vec::new();
-        match os::getenv_as_bytes(DynamicLibrary::envvar()) {
-            Some(env) => {
-                for portion in
-                        env.as_slice()
-                           .split(|a| *a == DynamicLibrary::separator()) {
-                    ret.push(Path::new(portion));
-                }
-            }
-            None => {}
-        }
-        return ret;
-    }
-
-    /// Access the value at the symbol of the dynamic library
-    pub unsafe fn symbol<T>(&self, symbol: &str) -> Result<T, String> {
-        // This function should have a lifetime constraint of 'a on
-        // T but that feature is still unimplemented
-
-        let maybe_symbol_value = dl::check_for_errors_in(|| {
-            symbol.with_c_str(|raw_string| {
-                dl::symbol(self.handle, raw_string)
-            })
-        });
-
-        // The value must not be constructed if there is an error so
-        // the destructor does not run.
-        match maybe_symbol_value {
-            Err(err) => Err(err),
-            Ok(symbol_value) => Ok(mem::transmute(symbol_value))
-        }
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use super::*;
-    use prelude::*;
-    use libc;
-
-    #[test]
-    #[ignore(cfg(windows))] // FIXME #8818
-    #[ignore(cfg(target_os="android"))] // FIXME(#10379)
-    fn test_loading_cosine() {
-        // The math library does not need to be loaded since it is already
-        // statically linked in
-        let none: Option<Path> = None; // appease the typechecker
-        let libm = match DynamicLibrary::open(none) {
-            Err(error) => fail!("Could not load self as module: {}", error),
-            Ok(libm) => libm
-        };
-
-        let cosine: extern fn(libc::c_double) -> libc::c_double = unsafe {
-            match libm.symbol("cos") {
-                Err(error) => fail!("Could not load function cos: {}", error),
-                Ok(cosine) => cosine
-            }
-        };
-
-        let argument = 0.0;
-        let expected_result = 1.0;
-        let result = cosine(argument);
-        if result != expected_result {
-            fail!("cos({:?}) != {:?} but equaled {:?} instead", argument,
-                   expected_result, result)
-        }
-    }
-
-    #[test]
-    #[cfg(target_os = "linux")]
-    #[cfg(target_os = "macos")]
-    #[cfg(target_os = "freebsd")]
-    fn test_errors_do_not_crash() {
-        // Open /dev/null as a library to get an error, and make sure
-        // that only causes an error, and not a crash.
-        let path = Path::new("/dev/null");
-        match DynamicLibrary::open(Some(&path)) {
-            Err(_) => {}
-            Ok(_) => fail!("Successfully opened the empty library.")
-        }
-    }
-}
-
-#[cfg(target_os = "linux")]
-#[cfg(target_os = "android")]
-#[cfg(target_os = "macos")]
-#[cfg(target_os = "freebsd")]
-pub mod dl {
-    use prelude::*;
-
-    use c_str::{CString, ToCStr};
-    use libc;
-    use ptr;
-    use result::*;
-    use str::StrAllocating;
-    use string::String;
-
-    pub unsafe fn open_external<T: ToCStr>(filename: T) -> *u8 {
-        filename.with_c_str(|raw_name| {
-            dlopen(raw_name, Lazy as libc::c_int) as *u8
-        })
-    }
-
-    pub unsafe fn open_internal() -> *u8 {
-        dlopen(ptr::null(), Lazy as libc::c_int) as *u8
-    }
-
-    pub fn check_for_errors_in<T>(f: || -> T) -> Result<T, String> {
-        use rt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
-        static mut lock: StaticNativeMutex = NATIVE_MUTEX_INIT;
-        unsafe {
-            // dlerror isn't thread safe, so we need to lock around this entire
-            // sequence
-            let _guard = lock.lock();
-            let _old_error = dlerror();
-
-            let result = f();
-
-            let last_error = dlerror();
-            let ret = if ptr::null() == last_error {
-                Ok(result)
-            } else {
-                Err(CString::new(last_error, false).as_str()
-                                                   .unwrap()
-                                                   .to_string())
-            };
-
-            ret
-        }
-    }
-
-    pub unsafe fn symbol(handle: *u8, symbol: *libc::c_char) -> *u8 {
-        dlsym(handle as *libc::c_void, symbol) as *u8
-    }
-    pub unsafe fn close(handle: *u8) {
-        dlclose(handle as *libc::c_void); ()
-    }
-
-    pub enum RTLD {
-        Lazy = 1,
-        Now = 2,
-        Global = 256,
-        Local = 0,
-    }
-
-    #[link_name = "dl"]
-    extern {
-        fn dlopen(filename: *libc::c_char, flag: libc::c_int) -> *libc::c_void;
-        fn dlerror() -> *libc::c_char;
-        fn dlsym(handle: *libc::c_void, symbol: *libc::c_char) -> *libc::c_void;
-        fn dlclose(handle: *libc::c_void) -> libc::c_int;
-    }
-}
-
-#[cfg(target_os = "win32")]
-pub mod dl {
-    use libc;
-    use os;
-    use ptr;
-    use result::{Ok, Err, Result};
-    use string::String;
-    use str;
-    use c_str::ToCStr;
-
-    pub unsafe fn open_external<T: ToCStr>(filename: T) -> *u8 {
-        // Windows expects Unicode data
-        let filename_cstr = filename.to_c_str();
-        let filename_str = str::from_utf8(filename_cstr.as_bytes_no_nul()).unwrap();
-        os::win32::as_utf16_p(filename_str, |raw_name| {
-            LoadLibraryW(raw_name as *libc::c_void) as *u8
-        })
-    }
-
-    pub unsafe fn open_internal() -> *u8 {
-        let handle = ptr::null();
-        GetModuleHandleExW(0 as libc::DWORD, ptr::null(), &handle as **libc::c_void);
-        handle as *u8
-    }
-
-    pub fn check_for_errors_in<T>(f: || -> T) -> Result<T, String> {
-        unsafe {
-            SetLastError(0);
-
-            let result = f();
-
-            let error = os::errno();
-            if 0 == error {
-                Ok(result)
-            } else {
-                Err(format!("Error code {}", error))
-            }
-        }
-    }
-
-    pub unsafe fn symbol(handle: *u8, symbol: *libc::c_char) -> *u8 {
-        GetProcAddress(handle as *libc::c_void, symbol) as *u8
-    }
-    pub unsafe fn close(handle: *u8) {
-        FreeLibrary(handle as *libc::c_void); ()
-    }
-
-    #[allow(non_snake_case_functions)]
-    extern "system" {
-        fn SetLastError(error: libc::size_t);
-        fn LoadLibraryW(name: *libc::c_void) -> *libc::c_void;
-        fn GetModuleHandleExW(dwFlags: libc::DWORD, name: *u16,
-                              handle: **libc::c_void) -> *libc::c_void;
-        fn GetProcAddress(handle: *libc::c_void, name: *libc::c_char) -> *libc::c_void;
-        fn FreeLibrary(handle: *libc::c_void);
-    }
-}
diff --git a/src/libstd/unstable/mod.rs b/src/libstd/unstable/mod.rs
deleted file mode 100644 (file)
index 985ef2e..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![doc(hidden)]
-
-pub mod dynamic_lib;
index 1b620185610e4f50c44b5854e30df21831e42dd1..723d0d60867f5ac679b88fedafb0a501af7240ec 100644 (file)
@@ -513,7 +513,7 @@ fn test_mutex_arc_poison() {
     #[test]
     fn test_mutex_arc_nested() {
         // Tests nested mutexes and access
-        // to underlaying data.
+        // to underlying data.
         let arc = Arc::new(Mutex::new(1));
         let arc2 = Arc::new(Mutex::new(arc));
         task::spawn(proc() {
index eb919198708096a4ae96c8a44e7739a1c070bf8e..bd4b5fae3d0922d74f8f35bc4c079b92bd9c6c36 100644 (file)
@@ -71,7 +71,7 @@ pub fn doit(&self, f: ||) {
 
         // Implementation-wise, this would seem like a fairly trivial primitive.
         // The stickler part is where our mutexes currently require an
-        // allocation, and usage of a `Once` should't leak this allocation.
+        // allocation, and usage of a `Once` shouldn't leak this allocation.
         //
         // This means that there must be a deterministic destroyer of the mutex
         // contained within (because it's not needed after the initialization
index 8fd10cdfa8b346a2751623ad73263e186dbd2ed6..821afeaa1f2e4b487b57bf0a04578ed873fe6ec8 100644 (file)
@@ -355,7 +355,7 @@ pub struct Semaphore {
 /// dropped, this value will release the resource back to the semaphore.
 #[must_use]
 pub struct SemaphoreGuard<'a> {
-    guard: SemGuard<'a, ()>,
+    _guard: SemGuard<'a, ()>,
 }
 
 impl Semaphore {
@@ -375,7 +375,7 @@ pub fn release(&self) { self.sem.release() }
     /// Acquire a resource of this semaphore, returning an RAII guard which will
     /// release the resource when dropped.
     pub fn access<'a>(&'a self) -> SemaphoreGuard<'a> {
-        SemaphoreGuard { guard: self.sem.access() }
+        SemaphoreGuard { _guard: self.sem.access() }
     }
 }
 
@@ -398,7 +398,7 @@ pub struct Mutex {
 /// corresponding mutex is also unlocked.
 #[must_use]
 pub struct MutexGuard<'a> {
-    guard: SemGuard<'a, Vec<WaitQueue>>,
+    _guard: SemGuard<'a, Vec<WaitQueue>>,
     /// Inner condition variable which is connected to the outer mutex, and can
     /// be used for atomic-unlock-and-deschedule.
     pub cond: Condvar<'a>,
@@ -421,7 +421,7 @@ pub fn new_with_condvars(num_condvars: uint) -> Mutex {
     /// also be accessed through the returned guard.
     pub fn lock<'a>(&'a self) -> MutexGuard<'a> {
         let SemCondGuard { guard, cvar } = self.sem.access_cond();
-        MutexGuard { guard: guard, cond: cvar }
+        MutexGuard { _guard: guard, cond: cvar }
     }
 }
 
index 2bc24fd1eb36994fa3801ed3cbfc6b6ebea0b044..2f5459b6f2e1b47801c1efcf6193f5495f95b26d 100644 (file)
@@ -175,6 +175,7 @@ pub struct DefId {
 pub enum TyParamBound {
     TraitTyParamBound(TraitRef),
     StaticRegionTyParamBound,
+    UnboxedFnTyParamBound(UnboxedFnTy),
     OtherRegionTyParamBound(Span) // FIXME -- just here until work for #5723 lands
 }
 
@@ -769,6 +770,11 @@ pub struct BareFnTy {
     pub decl: P<FnDecl>
 }
 
+#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
+pub struct UnboxedFnTy {
+    pub decl: P<FnDecl>,
+}
+
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub enum Ty_ {
     TyNil,
@@ -782,6 +788,7 @@ pub enum Ty_ {
     TyClosure(@ClosureTy, Option<Lifetime>),
     TyProc(@ClosureTy),
     TyBareFn(@BareFnTy),
+    TyUnboxedFn(@UnboxedFnTy),
     TyTup(Vec<P<Ty>> ),
     TyPath(Path, Option<OwnedSlice<TyParamBound>>, NodeId), // for #7264; see above
     TyTypeof(@Expr),
@@ -1046,6 +1053,15 @@ pub struct StructField_ {
     pub attrs: Vec<Attribute>,
 }
 
+impl StructField_ {
+    pub fn ident(&self) -> Option<Ident> {
+        match self.kind {
+            NamedField(ref ident, _) => Some(ident.clone()),
+            UnnamedField(_) => None
+        }
+    }
+}
+
 pub type StructField = Spanned<StructField_>;
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
index e81421cff043deb894c9bf60bba926c1473565ae..b656b0c06a06c2211d5041f10ac8ce29fb8c317c 100644 (file)
@@ -195,7 +195,7 @@ pub fn any(sp: Span) -> Box<MacResult> {
     /// Create a default MacResult that can only be an expression.
     ///
     /// Use this for macros that must expand to an expression, so even
-    /// if an error is encountered internally, the user will recieve
+    /// if an error is encountered internally, the user will receive
     /// an error that they also used it in the wrong place.
     pub fn expr(sp: Span) -> Box<MacResult> {
         box DummyResult { expr_only: true, span: sp } as Box<MacResult>
index 7b25f4db98075ad10cb29bbb4ec921e2752a5346..14769e3e510673aceb3ff5bf3a04dd04a0ea3aad 100644 (file)
 use parse::token::InternedString;
 use parse::token;
 
-pub struct Field {
-    ident: ast::Ident,
-    ex: @ast::Expr
-}
-
 // Transitional reexports so qquote can find the paths it is looking for
 mod syntax {
     pub use ext;
@@ -1000,9 +995,7 @@ fn view_use_glob(&self, sp: Span,
     }
 }
 
-struct Duplicator<'a> {
-    cx: &'a ExtCtxt<'a>,
-}
+struct Duplicator<'a>;
 
 impl<'a> Folder for Duplicator<'a> {
     fn new_id(&mut self, _: NodeId) -> NodeId {
@@ -1021,10 +1014,8 @@ pub trait Duplicate {
 }
 
 impl Duplicate for @ast::Expr {
-    fn duplicate(&self, cx: &ExtCtxt) -> @ast::Expr {
-        let mut folder = Duplicator {
-            cx: cx,
-        };
+    fn duplicate(&self, _: &ExtCtxt) -> @ast::Expr {
+        let mut folder = Duplicator;
         folder.fold_expr(*self)
     }
 }
index abe504b888579b86d06bd5d4eac44e7078a4d8c4..24cc286b190cf71d867b62998080022784d92bb2 100644 (file)
@@ -77,7 +77,7 @@ fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt, span: Span, substr: &Substru
             ```
 
             The optimiser should remove the redundancy. We explicitly
-            get use the binops to avoid auto-deref derefencing too many
+            get use the binops to avoid auto-deref dereferencing too many
             layers of pointers, if the type includes pointers.
             */
             let other_f = match other_fs {
index 228f5f02beea4779390a269161923b2dd3dce518..bf0da94e3e363d1a6f1f754f8d2b58bb39ffea36 100644 (file)
@@ -723,7 +723,7 @@ fn expand_struct_method_body(&self,
             &Struct(fields));
 
         // make a series of nested matches, to destructure the
-        // structs. This is actually right-to-left, but it shoudn't
+        // structs. This is actually right-to-left, but it shouldn't
         // matter.
         for (&arg_expr, &pat) in self_args.iter().zip(patterns.iter()) {
             body = cx.expr_match(trait_.span, arg_expr,
index 748ba6b19da60ead4ef329d9a8367a774bbd9539..c0c066fe4668b030fc8d36220cd4ba137211cf53 100644 (file)
@@ -58,7 +58,7 @@ pub fn new_tt_reader<'a>(sp_diag: &'a SpanHandler,
             dotdotdoted: false,
             sep: None,
         }),
-        interpolations: match interp { /* just a convienience */
+        interpolations: match interp { /* just a convenience */
             None => HashMap::new(),
             Some(x) => x,
         },
index 8903eb80829b4d7efd61bf0b48401d8a797470bb..03d0c283bcc5c522a81027e61cb6592fe9ad5707 100644 (file)
@@ -185,6 +185,11 @@ fn fold_ty(&mut self, t: P<Ty>) -> P<Ty> {
                     decl: self.fold_fn_decl(f.decl)
                 })
             }
+            TyUnboxedFn(ref f) => {
+                TyUnboxedFn(@UnboxedFnTy {
+                    decl: self.fold_fn_decl(f.decl),
+                })
+            }
             TyTup(ref tys) => TyTup(tys.iter().map(|&ty| self.fold_ty(ty)).collect()),
             TyPath(ref path, ref bounds, id) => {
                 let id = self.new_id(id);
@@ -440,6 +445,11 @@ fn fold_ty_param_bound<T: Folder>(tpb: &TyParamBound, fld: &mut T)
     match *tpb {
         TraitTyParamBound(ref ty) => TraitTyParamBound(fold_trait_ref(ty, fld)),
         StaticRegionTyParamBound => StaticRegionTyParamBound,
+        UnboxedFnTyParamBound(ref unboxed_function_type) => {
+            UnboxedFnTyParamBound(UnboxedFnTy {
+                decl: fld.fold_fn_decl(unboxed_function_type.decl),
+            })
+        }
         OtherRegionTyParamBound(s) => OtherRegionTyParamBound(s)
     }
 }
index 9dcc0877fa489783e449605e67f48ae26f0523cf..52e3693c31f2a1ad015538566bea41afc717da2c 100644 (file)
@@ -112,7 +112,7 @@ fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute {
     }
 
     // Parse attributes that appear after the opening of an item. These should
-    // be preceded by an exclaimation mark, but we accept and warn about one
+    // be preceded by an exclamation mark, but we accept and warn about one
     // terminated by a semicolon. In addition to a vector of inner attributes,
     // this function also returns a vector that may contain the first outer
     // attribute of the next item (since we can't know whether the attribute
index 4af4385e3c1da3bc05ef14ab47f02b5574155079..de5f533a96e1295a10f1d8c96dace3880458ccc7 100644 (file)
@@ -52,9 +52,9 @@
 use ast::{TypeField, TyFixedLengthVec, TyClosure, TyProc, TyBareFn};
 use ast::{TyTypeof, TyInfer, TypeMethod};
 use ast::{TyNil, TyParam, TyParamBound, TyPath, TyPtr, TyRptr};
-use ast::{TyTup, TyU32, TyUniq, TyVec, UnUniq};
-use ast::{UnnamedField, UnsafeBlock, UnsafeFn, ViewItem};
-use ast::{ViewItem_, ViewItemExternCrate, ViewItemUse};
+use ast::{TyTup, TyU32, TyUnboxedFn, TyUniq, TyVec, UnUniq};
+use ast::{UnboxedFnTy, UnboxedFnTyParamBound, UnnamedField, UnsafeBlock};
+use ast::{UnsafeFn, ViewItem, ViewItem_, ViewItemExternCrate, ViewItemUse};
 use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
 use ast::Visibility;
 use ast;
@@ -1058,15 +1058,27 @@ pub fn parse_ty_closure(&mut self) -> Ty_ {
             Vec::new()
         };
 
-        let inputs = if self.eat(&token::OROR) {
-            Vec::new()
+        let (is_unboxed, inputs) = if self.eat(&token::OROR) {
+            (false, Vec::new())
         } else {
             self.expect_or();
+
+            let is_unboxed = self.token == token::BINOP(token::AND) &&
+                self.look_ahead(1, |t| {
+                    token::is_keyword(keywords::Mut, t)
+                }) &&
+                self.look_ahead(2, |t| *t == token::COLON);
+            if is_unboxed {
+                self.bump();
+                self.bump();
+                self.bump();
+            }
+
             let inputs = self.parse_seq_to_before_or(
                 &token::COMMA,
                 |p| p.parse_arg_general(false));
             self.expect_or();
-            inputs
+            (is_unboxed, inputs)
         };
 
         let (region, bounds) = self.parse_optional_ty_param_bounds(true);
@@ -1079,13 +1091,19 @@ pub fn parse_ty_closure(&mut self) -> Ty_ {
             variadic: false
         });
 
-        TyClosure(@ClosureTy {
-            fn_style: fn_style,
-            onceness: onceness,
-            bounds: bounds,
-            decl: decl,
-            lifetimes: lifetimes,
-        }, region)
+        if is_unboxed {
+            TyUnboxedFn(@UnboxedFnTy {
+                decl: decl,
+            })
+        } else {
+            TyClosure(@ClosureTy {
+                fn_style: fn_style,
+                onceness: onceness,
+                bounds: bounds,
+                decl: decl,
+                lifetimes: lifetimes,
+            }, region)
+        }
     }
 
     pub fn parse_unsafety(&mut self) -> FnStyle {
@@ -2564,7 +2582,7 @@ pub fn parse_loop_expr(&mut self, opt_ident: Option<ast::Ident>) -> @Expr {
         self.mk_expr(lo, hi, ExprLoop(body, opt_ident))
     }
 
-    // For distingishing between struct literals and blocks
+    // For distinguishing between struct literals and blocks
     fn looking_at_struct_literal(&mut self) -> bool {
         self.token == token::LBRACE &&
         ((self.look_ahead(1, |t| token::is_plain_ident(t)) &&
@@ -3345,6 +3363,41 @@ fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
         })
     }
 
+    fn parse_unboxed_function_type(&mut self) -> UnboxedFnTy {
+        let inputs = if self.eat(&token::OROR) {
+            Vec::new()
+        } else {
+            self.expect_or();
+
+            if self.token == token::BINOP(token::AND) &&
+                    self.look_ahead(1, |t| {
+                        token::is_keyword(keywords::Mut, t)
+                    }) &&
+                    self.look_ahead(2, |t| *t == token::COLON) {
+                self.bump();
+                self.bump();
+                self.bump();
+            }
+
+            let inputs = self.parse_seq_to_before_or(&token::COMMA,
+                                                     |p| {
+                p.parse_arg_general(false)
+            });
+            self.expect_or();
+            inputs
+        };
+
+        let (return_style, output) = self.parse_ret_ty();
+        UnboxedFnTy {
+            decl: P(FnDecl {
+                inputs: inputs,
+                output: output,
+                cf: return_style,
+                variadic: false,
+            })
+        }
+    }
+
     // matches optbounds = ( ( : ( boundseq )? )? )
     // where   boundseq  = ( bound + boundseq ) | bound
     // and     bound     = 'static | ty
@@ -3394,6 +3447,11 @@ fn parse_optional_ty_param_bounds(&mut self, allow_any_lifetime: bool)
                     let tref = self.parse_trait_ref();
                     result.push(TraitTyParamBound(tref));
                 }
+                token::BINOP(token::OR) | token::OROR => {
+                    let unboxed_function_type =
+                        self.parse_unboxed_function_type();
+                    result.push(UnboxedFnTyParamBound(unboxed_function_type));
+                }
                 _ => break,
             }
 
index ec9ca65506458901793191a5d17b42bb787cc0f4..4fefa1f1d3d1ef07a215d9b751622ad0a9247038 100644 (file)
@@ -233,7 +233,7 @@ pub fn mk_printer(out: Box<io::Writer>, linewidth: uint) -> Printer {
  *
  * There is a parallel ring buffer, 'size', that holds the calculated size of
  * each token. Why calculated? Because for Begin/End pairs, the "size"
- * includes everything betwen the pair. That is, the "size" of Begin is
+ * includes everything between the pair. That is, the "size" of Begin is
  * actually the sum of the sizes of everything between Begin and the paired
  * End that follows. Since that is arbitrarily far in the future, 'size' is
  * being rewritten regularly while the printer runs; in fact most of the
@@ -434,7 +434,7 @@ pub fn advance_right(&mut self) {
         assert!((self.right != self.left));
     }
     pub fn advance_left(&mut self, x: Token, l: int) -> io::IoResult<()> {
-        debug!("advnce_left ~[{},{}], sizeof({})={}", self.left, self.right,
+        debug!("advance_left ~[{},{}], sizeof({})={}", self.left, self.right,
                self.left, l);
         if l >= 0 {
             let ret = self.print(x.clone(), l);
index 05c2558da486f80a45d909b39b4172df68c19f87..7cdc93c7314be097ea0475f6970136fdaf7a2b1d 100644 (file)
@@ -10,7 +10,7 @@
 
 use abi;
 use ast::{P, StaticRegionTyParamBound, OtherRegionTyParamBound,
-          TraitTyParamBound, Required, Provided};
+          TraitTyParamBound, UnboxedFnTyParamBound, Required, Provided};
 use ast;
 use ast_util;
 use owned_slice::OwnedSlice;
@@ -19,7 +19,6 @@
 use codemap;
 use diagnostic;
 use parse::classify::expr_is_simple_block;
-use parse::token::IdentInterner;
 use parse::token;
 use parse::lexer::comments;
 use parse;
@@ -30,7 +29,6 @@
 use std::io::{IoResult, MemWriter};
 use std::io;
 use std::mem;
-use std::rc::Rc;
 use std::str;
 use std::string::String;
 
@@ -58,7 +56,6 @@ pub struct CurrentCommentAndLiteral {
 pub struct State<'a> {
     pub s: pp::Printer,
     cm: Option<&'a CodeMap>,
-    intr: Rc<token::IdentInterner>,
     comments: Option<Vec<comments::Comment> >,
     literals: Option<Vec<comments::Literal> >,
     cur_cmnt_and_lit: CurrentCommentAndLiteral,
@@ -76,7 +73,6 @@ pub fn rust_printer_annotated<'a>(writer: Box<io::Writer>,
     State {
         s: pp::mk_printer(writer, default_columns),
         cm: None,
-        intr: token::get_ident_interner(),
         comments: None,
         literals: None,
         cur_cmnt_and_lit: CurrentCommentAndLiteral {
@@ -111,7 +107,6 @@ pub fn print_crate<'a>(cm: &'a CodeMap,
     let mut s = State {
         s: pp::mk_printer(out, default_columns),
         cm: Some(cm),
-        intr: token::get_ident_interner(),
         comments: Some(cmnts),
         // If the code is post expansion, don't use the table of
         // literals, since it doesn't correspond with the literals
@@ -505,27 +500,64 @@ pub fn print_type(&mut self, ty: &ast::Ty) -> IoResult<()> {
                     lifetimes: f.lifetimes.clone(),
                     ty_params: OwnedSlice::empty()
                 };
-                try!(self.print_ty_fn(Some(f.abi), None, &None,
-                                   f.fn_style, ast::Many, f.decl, None, &None,
-                                   Some(&generics), None));
+                try!(self.print_ty_fn(Some(f.abi),
+                                      None,
+                                      &None,
+                                      f.fn_style,
+                                      ast::Many,
+                                      f.decl,
+                                      None,
+                                      &None,
+                                      Some(&generics),
+                                      None,
+                                      false));
             }
             ast::TyClosure(f, ref region) => {
                 let generics = ast::Generics {
                     lifetimes: f.lifetimes.clone(),
                     ty_params: OwnedSlice::empty()
                 };
-                try!(self.print_ty_fn(None, Some('&'), region, f.fn_style,
-                                      f.onceness, f.decl, None, &f.bounds,
-                                      Some(&generics), None));
+                try!(self.print_ty_fn(None,
+                                      Some('&'),
+                                      region,
+                                      f.fn_style,
+                                      f.onceness,
+                                      f.decl,
+                                      None,
+                                      &f.bounds,
+                                      Some(&generics),
+                                      None,
+                                      false));
             }
             ast::TyProc(f) => {
                 let generics = ast::Generics {
                     lifetimes: f.lifetimes.clone(),
                     ty_params: OwnedSlice::empty()
                 };
-                try!(self.print_ty_fn(None, Some('~'), &None, f.fn_style,
-                                      f.onceness, f.decl, None, &f.bounds,
-                                      Some(&generics), None));
+                try!(self.print_ty_fn(None,
+                                      Some('~'),
+                                      &None,
+                                      f.fn_style,
+                                      f.onceness,
+                                      f.decl,
+                                      None,
+                                      &f.bounds,
+                                      Some(&generics),
+                                      None,
+                                      false));
+            }
+            ast::TyUnboxedFn(f) => {
+                try!(self.print_ty_fn(None,
+                                      None,
+                                      &None,
+                                      ast::NormalFn,
+                                      ast::Many,
+                                      f.decl,
+                                      None,
+                                      &None,
+                                      None,
+                                      None,
+                                      true));
             }
             ast::TyPath(ref path, ref bounds, _) => {
                 try!(self.print_bounded_path(path, bounds));
@@ -930,7 +962,8 @@ pub fn print_ty_method(&mut self, m: &ast::TypeMethod) -> IoResult<()> {
                               Some(m.ident),
                               &None,
                               Some(&m.generics),
-                              Some(m.explicit_self.node)));
+                              Some(m.explicit_self.node),
+                              false));
         word(&mut self.s, ";")
     }
 
@@ -1925,6 +1958,19 @@ pub fn print_bounds(&mut self,
                 try!(match *bound {
                     TraitTyParamBound(ref tref) => self.print_trait_ref(tref),
                     StaticRegionTyParamBound => word(&mut self.s, "'static"),
+                    UnboxedFnTyParamBound(ref unboxed_function_type) => {
+                        self.print_ty_fn(None,
+                                         None,
+                                         &None,
+                                         ast::NormalFn,
+                                         ast::Many,
+                                         unboxed_function_type.decl,
+                                         None,
+                                         &None,
+                                         None,
+                                         None,
+                                         true)
+                    }
                     OtherRegionTyParamBound(_) => Ok(())
                 })
             }
@@ -2112,8 +2158,9 @@ pub fn print_ty_fn(&mut self,
                        id: Option<ast::Ident>,
                        opt_bounds: &Option<OwnedSlice<ast::TyParamBound>>,
                        generics: Option<&ast::Generics>,
-                       opt_explicit_self: Option<ast::ExplicitSelf_>)
-        -> IoResult<()> {
+                       opt_explicit_self: Option<ast::ExplicitSelf_>,
+                       is_unboxed: bool)
+                       -> IoResult<()> {
         try!(self.ibox(indent_unit));
 
         // Duplicates the logic in `print_fn_header_info()`.  This is because that
@@ -2129,7 +2176,9 @@ pub fn print_ty_fn(&mut self,
             try!(self.print_fn_style(fn_style));
             try!(self.print_opt_abi_and_extern_if_nondefault(opt_abi));
             try!(self.print_onceness(onceness));
-            try!(word(&mut self.s, "fn"));
+            if !is_unboxed {
+                try!(word(&mut self.s, "fn"));
+            }
         }
 
         match id {
@@ -2143,15 +2192,20 @@ pub fn print_ty_fn(&mut self,
         match generics { Some(g) => try!(self.print_generics(g)), _ => () }
         try!(zerobreak(&mut self.s));
 
-        if opt_sigil == Some('&') {
+        if is_unboxed || opt_sigil == Some('&') {
             try!(word(&mut self.s, "|"));
         } else {
             try!(self.popen());
         }
 
+        if is_unboxed {
+            try!(word(&mut self.s, "&mut"));
+            try!(self.word_space(":"));
+        }
+
         try!(self.print_fn_args(decl, opt_explicit_self));
 
-        if opt_sigil == Some('&') {
+        if is_unboxed || opt_sigil == Some('&') {
             try!(word(&mut self.s, "|"));
         } else {
             if decl.variadic {
index 906f0c16f396478e0b904bc496962bf048a1c03d..a306ebba96aba22381d8c1ac3d707f18397f1d03 100644 (file)
@@ -62,7 +62,7 @@ pub fn generics_of_fn(fk: &FnKind) -> Generics {
 }
 
 /// Each method of the Visitor trait is a hook to be potentially
-/// overriden.  Each method's default implementation recursively visits
+/// overridden.  Each method's default implementation recursively visits
 /// the substructure of the input via the corresponding `walk` method;
 /// e.g. the `visit_mod` method by default calls `visit::walk_mod`.
 ///
@@ -383,6 +383,12 @@ pub fn walk_ty<E: Clone, V: Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) {
             walk_lifetime_decls(visitor, &function_declaration.lifetimes,
                                 env.clone());
         }
+        TyUnboxedFn(ref function_declaration) => {
+            for argument in function_declaration.decl.inputs.iter() {
+                visitor.visit_ty(argument.ty, env.clone())
+            }
+            visitor.visit_ty(function_declaration.decl.output, env.clone());
+        }
         TyPath(ref path, ref bounds, id) => {
             visitor.visit_path(path, id, env.clone());
             for bounds in bounds.iter() {
@@ -501,6 +507,13 @@ pub fn walk_ty_param_bounds<E: Clone, V: Visitor<E>>(visitor: &mut V,
                 walk_trait_ref_helper(visitor, typ, env.clone())
             }
             StaticRegionTyParamBound => {}
+            UnboxedFnTyParamBound(ref function_declaration) => {
+                for argument in function_declaration.decl.inputs.iter() {
+                    visitor.visit_ty(argument.ty, env.clone())
+                }
+                visitor.visit_ty(function_declaration.decl.output,
+                                 env.clone());
+            }
             OtherRegionTyParamBound(..) => {}
         }
     }
index 6b8ebb670e7b37963f1d3caf37546b124c99db08..0002b20d205ca9abaf930211a058d3ca2a8e8dd7 100644 (file)
@@ -32,7 +32,7 @@ pub fn get_dbpath_for_term(term: &str) -> Option<Box<Path>> {
         Some(dir) => dirs_to_search.push(Path::new(dir)),
         None => {
             if homedir.is_some() {
-                // ncurses compatability;
+                // ncurses compatibility;
                 dirs_to_search.push(homedir.unwrap().join(".terminfo"))
             }
             match getenv("TERMINFO_DIRS") {
index 9e562a08ff95e9a1ee893e1fba41804490711227..7d94e46a88a6e74b5769e57e1f5fc4e979422482 100644 (file)
@@ -271,6 +271,12 @@ pub fn test_main_static_x(args: &[~str], tests: &[TestDescAndFn]) {
                      tests)
 }
 
+pub enum ColorConfig {
+    AutoColor,
+    AlwaysColor,
+    NeverColor,
+}
+
 pub struct TestOpts {
     pub filter: Option<Regex>,
     pub run_ignored: bool,
@@ -282,6 +288,7 @@ pub struct TestOpts {
     pub test_shard: Option<(uint,uint)>,
     pub logfile: Option<Path>,
     pub nocapture: bool,
+    pub color: ColorConfig,
 }
 
 impl TestOpts {
@@ -298,6 +305,7 @@ fn new() -> TestOpts {
             test_shard: None,
             logfile: None,
             nocapture: false,
+            color: AutoColor,
         }
     }
 }
@@ -324,7 +332,11 @@ fn optgroups() -> Vec<getopts::OptGroup> {
       getopts::optopt("", "test-shard", "run shard A, of B shards, worth of the testsuite",
                      "A.B"),
       getopts::optflag("", "nocapture", "don't capture stdout/stderr of each \
-                                         task, allow printing directly"))
+                                         task, allow printing directly"),
+      getopts::optopt("", "color", "Configure coloring of output:
+            auto   = colorize if stdout is a tty and tests are run on serially (default);
+            always = always colorize output;
+            never  = never colorize output;", "auto|always|never"))
 }
 
 fn usage(binary: &str) {
@@ -406,6 +418,16 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
         nocapture = os::getenv("RUST_TEST_NOCAPTURE").is_some();
     }
 
+    let color = match matches.opt_str("color").as_ref().map(|s| s.as_slice()) {
+        Some("auto") | None => AutoColor,
+        Some("always") => AlwaysColor,
+        Some("never") => NeverColor,
+
+        Some(v) => return Some(Err(format!("argument for --color must be \
+                                            auto, always, or never (was {})",
+                                            v))),
+    };
+
     let test_opts = TestOpts {
         filter: filter,
         run_ignored: run_ignored,
@@ -417,6 +439,7 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
         test_shard: test_shard,
         logfile: logfile,
         nocapture: nocapture,
+        color: color,
     };
 
     Some(Ok(test_opts))
@@ -492,7 +515,7 @@ pub fn new(opts: &TestOpts,
         Ok(ConsoleTestState {
             out: out,
             log_out: log_out,
-            use_color: use_color(),
+            use_color: use_color(opts),
             total: 0u,
             passed: 0u,
             failed: 0u,
@@ -867,8 +890,12 @@ fn should_sort_failures_before_printing_them() {
     assert!(apos < bpos);
 }
 
-fn use_color() -> bool {
-    get_concurrency() == 1 && io::stdout().get_ref().isatty()
+fn use_color(opts: &TestOpts) -> bool {
+    match opts.color {
+        AutoColor => get_concurrency() == 1 && io::stdout().get_ref().isatty(),
+        AlwaysColor => true,
+        NeverColor => false,
+    }
 }
 
 #[deriving(Clone)]
index 2459a7fc273a99cd046ec702e5aa171e7cf3e74a..bace30e3f6ffd1dc5afbdbd842fa305ca1d4724a 100644 (file)
@@ -462,7 +462,7 @@ impl FromStr for Uuid {
     /// Parse a hex string and interpret as a UUID
     ///
     /// Accepted formats are a sequence of 32 hexadecimal characters,
-    /// with or without hypens (grouped as 8, 4, 4, 4, 12).
+    /// with or without hyphens (grouped as 8, 4, 4, 4, 12).
     fn from_str(us: &str) -> Option<Uuid> {
         let result = Uuid::parse_string(us);
         match result {
@@ -492,7 +492,7 @@ impl Eq for Uuid {}
 
 // FIXME #9845: Test these more thoroughly
 impl<T: Encoder<E>, E> Encodable<T, E> for Uuid {
-    /// Encode a UUID as a hypenated string
+    /// Encode a UUID as a hyphenated string
     fn encode(&self, e: &mut T) -> Result<(), E> {
         e.emit_str(self.to_hyphenated_str().as_slice())
     }
index 4ae0b6f14f59d4fcd009a629edf46aa8f0e38b55..0b4bea49fa2499d0481dbdcbe5178c20c8401fe9 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::unstable::dynamic_lib::DynamicLibrary;
+use std::dynamic_lib::DynamicLibrary;
 
 #[no_mangle]
 pub fn foo() { bar(); }
diff --git a/src/test/compile-fail/issue-13446.rs b/src/test/compile-fail/issue-13446.rs
new file mode 100644 (file)
index 0000000..0bb6ded
--- /dev/null
@@ -0,0 +1,17 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+// Used to cause ICE
+
+static VEC: [u32, ..256] = vec!(); //~ ERROR mismatched types
+
+fn main() {}
+
index 10734f1f2430ae9ff323648bdb9438eb4d79c148..bca2a5d7edc864cb871726e4603157fbe8bdc424 100644 (file)
@@ -39,7 +39,10 @@ mod foo2 {
 pub type typ = *UsedStruct4;
 pub struct PubStruct();
 struct PrivStruct; //~ ERROR: code is never used
-struct UsedStruct1 { x: int }
+struct UsedStruct1 {
+    #[allow(dead_code)]
+    x: int
+}
 struct UsedStruct2(int);
 struct UsedStruct3;
 struct UsedStruct4;
@@ -53,6 +56,7 @@ fn la_la_la() {}
 struct StructUsedInEnum;
 struct StructUsedInGeneric;
 pub struct PubStruct2 {
+    #[allow(dead_code)]
     struct_used_as_field: *StructUsedAsField
 }
 
diff --git a/src/test/compile-fail/lint-dead-code-4.rs b/src/test/compile-fail/lint-dead-code-4.rs
new file mode 100644 (file)
index 0000000..718af18
--- /dev/null
@@ -0,0 +1,67 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(struct_variant)]
+#![allow(unused_variable)]
+#![allow(non_camel_case_types)]
+#![deny(dead_code)]
+
+extern crate libc;
+
+use std::num;
+
+struct Foo {
+    x: uint,
+    b: bool, //~ ERROR: code is never used
+    marker: std::kinds::marker::NoCopy
+}
+
+fn field_read(f: Foo) -> uint {
+    num::pow(f.x, 2)
+}
+
+enum XYZ {
+    X,
+    Y {
+        a: String,
+        b: int //~ ERROR: code is never used
+    },
+    Z
+}
+
+fn field_match_in_patterns(b: XYZ) -> String {
+    match b {
+        Y { a: a, .. } => a,
+        _ => "".to_string()
+    }
+}
+
+struct Bar {
+    x: uint, //~ ERROR: code is never used
+    b: bool,
+    _guard: ()
+}
+
+#[repr(C)]
+struct Baz {
+    x: libc::c_uint
+}
+
+fn field_match_in_let(f: Bar) -> bool {
+    let Bar { b, .. } = f;
+    b
+}
+
+fn main() {
+    field_read(Foo { x: 1, b: false, marker: std::kinds::marker::NoCopy });
+    field_match_in_patterns(Z);
+    field_match_in_let(Bar { x: 42u, b: true, _guard: () });
+    let _ = Baz { x: 0 };
+}
index d9a79d7597592c286ad66b9a024ab941fd4e019c..ff382cb46c7624ec123d956f592915110341a523 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![allow(dead_code)]
 #![feature(managed_boxes)]
 #![forbid(managed_heap_memory)]
 
index c9688ad49d77e3609eef7431c2fe2926c5bc2d20..8f20999a56c8d7064d6848bf29e8ed1e63da4539 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![allow(dead_code)]
 #![forbid(owned_heap_memory)]
 
 
index 386b4019485a91cc66a59795371b175bb33cbaae..f1b36d719e9591603450e80b089e4a3d031aa4ea 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![allow(dead_code)]
 #![deny(uppercase_variables)]
 
 use std::io::File;
index e05d43145d7e2e365d3004113989ca814dde77da..0f759efb02539bc874d624f4511cd767b819f89e 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::unstable::dynamic_lib::DynamicLibrary;
+use std::dynamic_lib::DynamicLibrary;
 use std::os;
 
 pub fn main() {
diff --git a/src/test/run-pass/fn-trait-sugar.rs b/src/test/run-pass/fn-trait-sugar.rs
new file mode 100644 (file)
index 0000000..b0c8d84
--- /dev/null
@@ -0,0 +1,38 @@
+
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(unboxed_closure_sugar)]
+
+use std::ops::FnMut;
+
+struct S;
+
+impl FnMut<(int,),int> for S {
+    fn call_mut(&mut self, (x,): (int,)) -> int {
+        x * x
+    }
+}
+
+fn call_it<F:|int|->int>(mut f: F, x: int) -> int {
+    f.call_mut((x,)) + 3
+}
+
+fn call_box(f: &mut |&mut: int|->int, x: int) -> int {
+    f.call_mut((x,)) + 3
+}
+
+fn main() {
+    let x = call_it(S, 1);
+    let y = call_box(&mut S, 1);
+    assert!(x == 4);
+    assert!(y == 4);
+}
+
diff --git a/src/test/run-pass/issue-11940.rs b/src/test/run-pass/issue-11940.rs
new file mode 100644 (file)
index 0000000..bbe7eff
--- /dev/null
@@ -0,0 +1,19 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+static TEST_STR: &'static str = "abcd";
+
+fn main() {
+    let s = "abcd";
+    match s {
+        TEST_STR => (),
+        _ => unreachable!()
+    }
+}
index e263767990a65d188dd08e823a41788308d8fd4f..58f66314e4430dd7fca25b6b6046b192787d9eb1 100644 (file)
@@ -10,7 +10,7 @@
 
 // aux-build:linkage-visibility.rs
 // ignore-android: FIXME(#10379)
-// ignore-win32: std::unstable::dynamic_lib does not work on win32 well
+// ignore-win32: std::dynamic_lib does not work on win32 well
 
 extern crate foo = "linkage-visibility";